returning a subclass through an interface

Discussion in 'Java' started by Andy Fish, Nov 10, 2004.

  1. Andy Fish

    Andy Fish Guest

    Hi,

    I am writing an API call which returns an object of type X. In my code, I
    build an object which is of type Y - a subclass of X.

    I'm worried that if I return the object Y, the caller will be able to use
    reflection or a debugger to find out about the extra properties of Y. Is
    this concern valid or is there something inherent that stops him doing this?

    assuming my concern is valid, I need to make a "clone" of Y but for the
    clone to be a superclass (i.e. X). Is there any clever way of doing this?
    The class X only contains public immutable properties and has no methods so
    there is no need to deep copy.

    TIA

    Andy
    Andy Fish, Nov 10, 2004
    #1
    1. Advertising

  2. Andy Fish

    Chris Uppal Guest

    Andy Fish wrote:

    > I am writing an API call which returns an object of type X. In my code, I
    > build an object which is of type Y - a subclass of X.
    >
    > I'm worried that if I return the object Y, the caller will be able to use
    > reflection or a debugger to find out about the extra properties of Y. Is
    > this concern valid or is there something inherent that stops him doing
    > this?


    There's nothing much stopping it; if Y is public then the caller could even
    just downcast the "X" into a Y.

    I'm curious as to why you want the extra protection ? It's not normally
    something that you need.


    > assuming my concern is valid, I need to make a "clone" of Y but for the
    > clone to be a superclass (i.e. X). Is there any clever way of doing this?
    > The class X only contains public immutable properties and has no methods
    > so there is no need to deep copy.


    ?? Has no methods ??

    Anyway, assuming that you don't mean that the way it sounds (and also assuming
    that you have good reason to want give your "Y" more protection than the
    language directly affords), what you could do is return an object that
    /contains/ your Y, and implements the public methods of X by delagating them to
    the Y.

    Of course, that would still be open to abuse -- there's no way of preventing
    someone using a debugger, or reflection (plus an open security policy), or JNI,
    or even a custom JVM, from "getting at" the Y.

    -- chris
    Chris Uppal, Nov 10, 2004
    #2
    1. Advertising

  3. Andy Fish

    xarax Guest

    "Chris Uppal" <-THIS.org> wrote in message
    news:...
    > Andy Fish wrote:
    >
    > > I am writing an API call which returns an object of type X. In my code, I
    > > build an object which is of type Y - a subclass of X.
    > >
    > > I'm worried that if I return the object Y, the caller will be able to use
    > > reflection or a debugger to find out about the extra properties of Y. Is
    > > this concern valid or is there something inherent that stops him doing
    > > this?

    >
    > There's nothing much stopping it; if Y is public then the caller could even
    > just downcast the "X" into a Y.
    >
    > I'm curious as to why you want the extra protection ? It's not normally
    > something that you need.
    >
    >
    > > assuming my concern is valid, I need to make a "clone" of Y but for the
    > > clone to be a superclass (i.e. X). Is there any clever way of doing this?
    > > The class X only contains public immutable properties and has no methods
    > > so there is no need to deep copy.

    >
    > ?? Has no methods ??
    >
    > Anyway, assuming that you don't mean that the way it sounds (and also assuming
    > that you have good reason to want give your "Y" more protection than the
    > language directly affords), what you could do is return an object that
    > /contains/ your Y, and implements the public methods of X by delagating them

    to
    > the Y.
    >
    > Of course, that would still be open to abuse -- there's no way of preventing
    > someone using a debugger, or reflection (plus an open security policy), or

    JNI,
    > or even a custom JVM, from "getting at" the Y.


    The general approach to prevent downcasting is to
    protect the subtype somehow. (Forget about stopping
    a debugger. There may be someway to prevent the
    debugger from seeing the true type using a security
    mechanism, but I don't know how or why you would
    do that.)

    Another way is to specify the super class as an
    interface type and use a protected/private inner
    class to implement that interface. Downcasting
    would not show anything useful.
    xarax, Nov 10, 2004
    #3
  4. Andy Fish wrote:

    > I am writing an API call which returns an object of type X. In my code, I
    > build an object which is of type Y - a subclass of X.
    >
    > I'm worried that if I return the object Y, the caller will be able to use
    > reflection or a debugger to find out about the extra properties of Y. Is
    > this concern valid or is there something inherent that stops him doing this?


    Pretty much nothing prevents such analysis. On the other hand, nothing
    prevents a user from digging Y.class out of your jar and running it
    through javap, either. As to whether or not the concern is _valid_, I'd
    say you need to make a good case for why the caller must *at all costs*
    be prevented from doing what you describe before I would accept the
    concern as valid.

    > assuming my concern is valid, I need to make a "clone" of Y but for the
    > clone to be a superclass (i.e. X). Is there any clever way of doing this?


    Construct and return an X in the first place? I don't see the point of
    an object that is not an X, but yet is indistinguishable from one
    despite scrutiny.

    > The class X only contains public immutable properties and has no methods so
    > there is no need to deep copy.


    I hope you don't mean that X exposes its fields to the world. As long
    as access to its properties goes through accessor methods you have a
    great deal of flexibility, including a variety of ways to accomplish
    some of the things I imagine you might be trying to do. Before I make
    any specific recommendation, however, I need to know what things you
    actually are trying to do. (I have a vivid imagination. :) )


    John Bollinger
    John C. Bollinger, Nov 10, 2004
    #4
  5. Andy Fish

    Andy Fish Guest

    "John C. Bollinger" <> wrote in message
    news:cmtacg$jgs$...
    > Andy Fish wrote:
    >
    >> I am writing an API call which returns an object of type X. In my code, I
    >> build an object which is of type Y - a subclass of X.
    >>
    >> I'm worried that if I return the object Y, the caller will be able to use
    >> reflection or a debugger to find out about the extra properties of Y. Is
    >> this concern valid or is there something inherent that stops him doing
    >> this?

    >
    > Pretty much nothing prevents such analysis. On the other hand, nothing
    > prevents a user from digging Y.class out of your jar and running it
    > through javap, either. As to whether or not the concern is _valid_, I'd
    > say you need to make a good case for why the caller must *at all costs* be
    > prevented from doing what you describe before I would accept the concern
    > as valid.
    >
    >> assuming my concern is valid, I need to make a "clone" of Y but for the
    >> clone to be a superclass (i.e. X). Is there any clever way of doing this?

    >
    > Construct and return an X in the first place? I don't see the point of an
    > object that is not an X, but yet is indistinguishable from one despite
    > scrutiny.
    >
    >> The class X only contains public immutable properties and has no methods
    >> so there is no need to deep copy.

    >
    > I hope you don't mean that X exposes its fields to the world. As long as
    > access to its properties goes through accessor methods you have a great
    > deal of flexibility, including a variety of ways to accomplish some of the
    > things I imagine you might be trying to do. Before I make any specific
    > recommendation, however, I need to know what things you actually are
    > trying to do. (I have a vivid imagination. :) )
    >


    OK, here's a sample. The API returns a PersonDTO (Data Transfer Object). to
    do this, it gets a rich, functional 'person' object (meant for internal use
    only) from the business services and copies the information into the DTO.

    PersonDTO getPersonDetails (int personId) {
    PersonObject p = BusinessServices.GetPerson(personId);
    PersonDetails pd = new PersonDetails();
    pd.firstName = p.firstName;
    pd.lastName = p.lastName;
    pd.AddressLine1 = p.AddressLine1;
    ... etc etc
    return pd;
    }

    now, if PersonObject was a subclass of PersonDTO, I wouldn't have to copy
    all the fields; I could just return p. However, there are some properties of
    PersonObject I definitely don't want the caller to know about.

    Andy


    >
    > John Bollinger
    >
    Andy Fish, Nov 11, 2004
    #5
  6. On Thu, 11 Nov 2004 10:53:10 GMT, Andy Fish <>
    wrote:

    >
    > OK, here's a sample. The API returns a PersonDTO (Data Transfer Object).
    > to
    > do this, it gets a rich, functional 'person' object (meant for internal
    > use
    > only) from the business services and copies the information into the DTO.
    >
    > PersonDTO getPersonDetails (int personId) {
    > PersonObject p = BusinessServices.GetPerson(personId);
    > PersonDetails pd = new PersonDetails();
    > pd.firstName = p.firstName;
    > pd.lastName = p.lastName;
    > pd.AddressLine1 = p.AddressLine1;
    > ... etc etc
    > return pd;
    > }
    >
    > now, if PersonObject was a subclass of PersonDTO, I wouldn't have to copy
    > all the fields; I could just return p. However, there are some
    > properties of
    > PersonObject I definitely don't want the caller to know about.


    I'd use a Decorator that implements PersonDTO, but denies any further
    operations. This will (of course) not be debug-proof, but the attacker
    might just as well look at the Info while your new object is constructed,
    so you will not achive 100% security in any case.


    --

    Whom the gods wish to destroy they first call promising.
    Stefan Schulz, Nov 11, 2004
    #6
  7. Andy Fish wrote:
    > OK, here's a sample. The API returns a PersonDTO (Data Transfer Object). to
    > do this, it gets a rich, functional 'person' object (meant for internal use
    > only) from the business services and copies the information into the DTO.
    >
    > PersonDTO getPersonDetails (int personId) {
    > PersonObject p = BusinessServices.GetPerson(personId);
    > PersonDetails pd = new PersonDetails();
    > pd.firstName = p.firstName;
    > pd.lastName = p.lastName;
    > pd.AddressLine1 = p.AddressLine1;
    > ... etc etc
    > return pd;
    > }
    >
    > now, if PersonObject was a subclass of PersonDTO, I wouldn't have to copy
    > all the fields; I could just return p. However, there are some properties of
    > PersonObject I definitely don't want the caller to know about.


    That doesn't tell me anything I hadn't already gleaned from your last
    message. What I don't understand is why it is not sufficient that the
    method's return type is specified as PersonDTO. Yes, a malicious
    programmer who obtained your library could hack into the details at
    runtime via reflection or a debugger, but is that an eventuality that
    you really need to worry about? Is it more serious than the possibility
    that the same malicious programmer might extract any class he wants from
    your library jar and decompile it? Or even insert a modified version?
    Is the program even going to run in an environment that exposes it to
    these risks?

    You would gain some measure of protection by making PersonObject
    package-private (if you haven't already) but someone seriously out to
    crack your code _will_. What are the consequences if someone does? Is
    partial protection against those consequences worth the effort?

    In general I wonder whether your application might benefit from some
    refactoring. The concept of making PersonObject a subclass of PersonDTO
    simply to avoid copying fields seems rather strange to me (and the idea
    is the source of your present problem). I can't comment further on
    that, however, because I haven't enough code to see the big picture.


    John Bollinger
    John C. Bollinger, Nov 11, 2004
    #7
  8. Andy Fish

    Andy Fish Guest

    "John C. Bollinger" <> wrote in message
    news:cmvpro$ee7$...
    > Andy Fish wrote:
    >> OK, here's a sample. The API returns a PersonDTO (Data Transfer Object).
    >> to do this, it gets a rich, functional 'person' object (meant for
    >> internal use only) from the business services and copies the information
    >> into the DTO.
    >>
    >> PersonDTO getPersonDetails (int personId) {
    >> PersonObject p = BusinessServices.GetPerson(personId);
    >> PersonDetails pd = new PersonDetails();
    >> pd.firstName = p.firstName;
    >> pd.lastName = p.lastName;
    >> pd.AddressLine1 = p.AddressLine1;
    >> ... etc etc
    >> return pd;
    >> }
    >>
    >> now, if PersonObject was a subclass of PersonDTO, I wouldn't have to copy
    >> all the fields; I could just return p. However, there are some properties
    >> of PersonObject I definitely don't want the caller to know about.

    >
    > That doesn't tell me anything I hadn't already gleaned from your last
    > message. What I don't understand is why it is not sufficient that the
    > method's return type is specified as PersonDTO. Yes, a malicious
    > programmer who obtained your library could hack into the details at
    > runtime via reflection or a debugger, but is that an eventuality that you
    > really need to worry about? Is it more serious than the possibility that
    > the same malicious programmer might extract any class he wants from your
    > library jar and decompile it? Or even insert a modified version? Is the
    > program even going to run in an environment that exposes it to these
    > risks?
    >


    Thanks John (and others) for the replies. What I was concerned about is, say
    the person object contains details about that person's privileges. If a
    hacker could change those privileges with a debugger they might be able to
    do things they aren't supposed to do.

    However, I take your point about decompiling. If someone running in the same
    JVM wanted to get those privileges they ultimately could, because in the end
    my code is just a bunch of routines that access some underlying data store,
    and the JVM must have access to that data store.

    so I guess cases where I realistically need to worry about being hacked are
    where someone is calling the API from outside the JVM (e.g. SOAP). In this
    case, as long as I ensure that only the public fields (i.e. those from
    PersonDTO) get transmitted across the wire, I am OK.

    Unfortunately that brings up another problem - to maximise the ability of
    reusing the interface in different places, the DTO object should be
    serializable. However, the Person object will definitely not be serialisable
    so that might put the kibosh on the whole idea

    > You would gain some measure of protection by making PersonObject
    > package-private (if you haven't already) but someone seriously out to
    > crack your code _will_. What are the consequences if someone does? Is
    > partial protection against those consequences worth the effort?
    >
    > In general I wonder whether your application might benefit from some
    > refactoring. The concept of making PersonObject a subclass of PersonDTO
    > simply to avoid copying fields seems rather strange to me (and the idea is
    > the source of your present problem). I can't comment further on that,
    > however, because I haven't enough code to see the big picture.
    >
    >
    > John Bollinger
    >
    Andy Fish, Nov 11, 2004
    #8
  9. On Thu, 11 Nov 2004 14:05:40 GMT, Andy Fish <>
    wrote:

    >
    > Thanks John (and others) for the replies. What I was concerned about is,
    > say the person object contains details about that person's privileges. If
    > a hacker could change those privileges with a debugger they might be
    > able to do things they aren't supposed to do.


    In that case you definitly need to re-think your security design. You
    should
    always authorize any "privileged" operation in the operation context, not
    in some user context. You should also keep authorization information
    directly
    tied to some user (maybe by using a Certificate for that user)

    Ultimately, however, if your cracker has your application in her debugger,
    you've lost anyway. She can just remove the access check methods, or make
    them accept anything.

    > However, I take your point about decompiling. If someone running in the
    > same JVM wanted to get those privileges they ultimately could, becausein
    > the end my code is just a bunch of routines that access someunderlying
    > data store, and the JVM must have access to that data store.


    Exactly.

    > so I guess cases where I realistically need to worry about being hacked
    > are where someone is calling the API from outside the JVM (e.g. SOAP).
    > In this case, as long as I ensure that only the public fields (i.e. those
    > from PersonDTO) get transmitted across the wire, I am OK.


    Exactly.

    > Unfortunately that brings up another problem - to maximise the ability of
    > reusing the interface in different places, the DTO object should be
    > serializable. However, the Person object will definitely not be
    > serialisable so that might put the kibosh on the whole idea


    This merely goes to show that the Person class should not inherit from
    DataTransferObject, but instead have some createDTA() method that
    constructs one.


    --

    Whom the gods wish to destroy they first call promising.
    Stefan Schulz, Nov 11, 2004
    #9
  10. Andy Fish

    Yamin Guest

    "Andy Fish" <> wrote in message news:<UkKkd.12000$>...

    <snip>
    > "John C. Bollinger" <> wrote in message
    > news:cmvpro$ee7$...
    > > Andy Fish wrote:

    > Thanks John (and others) for the replies. What I was concerned about is, say
    > the person object contains details about that person's privileges. If a
    > hacker could change those privileges with a debugger they might be able to
    > do things they aren't supposed to do.
    >
    > However, I take your point about decompiling. If someone running in the same
    > JVM wanted to get those privileges they ultimately could, because in the end
    > my code is just a bunch of routines that access some underlying data store,
    > and the JVM must have access to that data store.
    >
    > so I guess cases where I realistically need to worry about being hacked are
    > where someone is calling the API from outside the JVM (e.g. SOAP). In this
    > case, as long as I ensure that only the public fields (i.e. those from
    > PersonDTO) get transmitted across the wire, I am OK.


    There are cases that you WILL need to worry this. Never worry about
    someone debugging the code as they can debug any code. You shouldn't
    even worry about people calling it outside the JVM. Things you should
    worry about are:

    1. If the person object is going to be saved to a file. Then you do
    have a security problem. One that should force you to override some
    of the encoding or better yet, make it a separate type.

    2. If it is going to be sent over a network via RPC or other means.
    Once again, your raw data now in the person object is going to be
    visible by others snooping on the line, or someone who writes a
    customized receiver (client program).

    3. If you guys leave debug/toString statements in code that might
    print out the more detailed information.

    ....
    Yamin
    Yamin, Nov 11, 2004
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. sks
    Replies:
    2
    Views:
    392
    Ingo R. Homann
    Aug 29, 2005
  2. jstorta
    Replies:
    3
    Views:
    441
    jstorta
    Feb 20, 2006
  3. S.Volkov
    Replies:
    2
    Views:
    215
    S.Volkov
    Mar 12, 2006
  4. Trans
    Replies:
    8
    Views:
    320
    Robert Klemme
    Oct 23, 2008
  5. Fab

    Subclass of subclass

    Fab, Aug 9, 2012, in forum: C++
    Replies:
    0
    Views:
    394
Loading...

Share This Page