Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / December 2006

Tip: Looking for answers? Try searching our database.

Need a new access modifier?

Thread view: 
John Ersatznom - 27 Dec 2006 01:32 GMT
I've read somewhere that inner class access to a "private" member of a
nesting class causes it to be silently treated as "package-private" by
the compiler, with security implications.

Silently changing the semantics of a security-influencing construct in
the language strikes me as bad form.

This suggests that either the implementation of inner classes needs to
change (this smells like a kludge to me), or a more elegant workaround
needs developing.

The idea that occurred to me is a new access modifier, besides
"private", "public", and "protected". The new modifier would grant
access to inner classes but not to subclasses, and not to other classes
in the same package -- only to ones nested in the correct parent class.

I don't know what its name should be. Making it blank and making the
"package" keyword do double duty as the access modifier for
package-private members sounds clean but isn't source-compatible with
older code at all -- package-private members suddenly become effectively
private, in fact, in a lot of old code if that gets done.

So it needs a new name (though allowing "package" as an explicit
access-modifier is something I'd also support, while leaving it the
default access as well). I don't know if any existing keyword is a good
choice, however. Perhaps "class", to indicate access throughout a class.
Or perhaps "private", relinquishing any "private even from inner
classes" access level, which amounts to simply getting rid of the
hackish workaround so that nested classes have access but other stuff in
the same package does not.

Or, I suppose, someone could find a way to make a package secure against
the injection of a hostile class. Maybe making the class loader reject a
class that belongs to a package where a) another class that belongs to
that package has the same name as the package's name's last
dot-separated part, but with the first letter capitalizaed and b) that
class is in a jar and the class being loaded either isn't or is in a
different jar. Then you can make com.foo.my.package contain a class
Package and stick your package in a signed jar, and nobody can sneak a
class into your package because a) if they don't put it into that same
jar the classloader will reject it but b) if they do the jar signature
won't match up and if you publish its MD5-sum this makes it
tamper-evident. Using "the jar that contains a class with the same name
as the package" to define the "official" jar for a package breaks
symmetry; otherwise someone throwing in their own jar with their own
classes in a same-named package creates an ambiguity: which set of
classes to reject for security reasons and which to accept? Now the
class loader keeps the set containing the marker-class. (If classes with
the same fully-qualified name are present in two different-MD5-sum jars
along the class path, the whole system can grind to a halt and complain
of a grievous error, since there is one.)
John W. Kennedy - 27 Dec 2006 02:14 GMT
> I've read somewhere that inner class access to a "private" member of a
> nesting class causes it to be silently treated as "package-private" by
> the compiler, with security implications.

A quick test seems to contradict this. "private" appears to be "private".

Signature

John W. Kennedy
"The blind rulers of Logres
Nourished the land on a fallacy of rational virtue."
  -- Charles Williams.  "Taliessin through Logres: Prelude"

Patricia Shanahan - 27 Dec 2006 03:39 GMT
>> I've read somewhere that inner class access to a "private" member of a
>> nesting class causes it to be silently treated as "package-private" by
>> the compiler, with security implications.
>
> A quick test seems to contradict this. "private" appears to be "private".

I think there is a difference between compile time and run time
treatment in this area.

"private" is enforced at compile time. However, even if the inner class
is declared "private" the generated class file for it has default access
to allow its parent class to access it.

I think the key issue here is whether access to classes from inside the
same package has security implications or not. The current treatment is
good enough to prevent accidental misuse by a non-malicious programmer.

Patricia
Chris Smith - 27 Dec 2006 04:02 GMT
> I think the key issue here is whether access to classes from inside the
> same package has security implications or not. The current treatment is
> good enough to prevent accidental misuse by a non-malicious programmer.

Yes, absolutely.  The private keyword is best treated as having no
security significance at all.  Package access is the significant bit for
some security purposes.  (In general, though, I tend to think that many
people over-estimate the relevance of access specifiers to security in
the first place; it only matters when one is installing a new
SecurityManager and running untrusted code within the context of the
application.)

Signature

Chris Smith

John Ersatznom - 27 Dec 2006 04:14 GMT
> I think the key issue here is whether access to classes from inside the
> same package has security implications or not. The current treatment is
> good enough to prevent accidental misuse by a non-malicious programmer.

Unfortunately, we all know what happens when a security mechanism is
designed around the threat model of "accidental misuse by a
non-malicious programmer", don't we? :)
Patricia Shanahan - 27 Dec 2006 04:18 GMT
>> I think the key issue here is whether access to classes from inside the
>> same package has security implications or not. The current treatment is
[quoted text clipped - 3 lines]
> designed around the threat model of "accidental misuse by a
> non-malicious programmer", don't we? :)

Of course. The question I'm asking is whether the distinction between
private and package access should be considered part of the security
model at all.

Do you think it should, and if so, why?

Patricia
John Ersatznom - 27 Dec 2006 07:40 GMT
>>> I think the key issue here is whether access to classes from inside the
>>> same package has security implications or not. The current treatment is
[quoted text clipped - 9 lines]
>
> Do you think it should, and if so, why?

Either it should, or package access should be easier to lock down.
Anyone can put a class in your package simply by including "package
yourpackagename;" at the start of the code, after all. The key to
locking out such classes would probably be at the level of jar files.
You'd have to have some way for one such file to be the "canonical" one
for a given package, and then prevent class-loading anything into that
package that isn't from that jar. Making that jar tamper-evident with an
MD5 sum or similar (e.g. making it a signed jar) would then complete the
picture. The trick is dealing with the case that there's multiple jars
for a package. Which one is the "right" one? Specifying it (by MD5 or
similar hash) for every security-sensitive package in another
tamper-evident file for which there's no ambiguity is one option. That
file would be per-application rather than per-jar. Another is to use
whichever jar has a class named the same as the package in question, and
consider any case of having different jars (different hash) with classes
with the same (fully qualified) name, named after the containing
package, to be an error (and any case of nonidentical classes sharing a
fully-qualified name an error, but I expect that's already the case).
Chris Smith - 27 Dec 2006 15:17 GMT
> Either it should, or package access should be easier to lock down.
> Anyone can put a class in your package simply by including "package
> yourpackagename;" at the start of the code, after all. The key to
> locking out such classes would probably be at the level of jar files.

Again, google "Java sealed package".  This already exists.

Signature

Chris Smith

John Ersatznom - 27 Dec 2006 04:13 GMT
>> I've read somewhere that inner class access to a "private" member of a
>> nesting class causes it to be silently treated as "package-private" by
>> the compiler, with security implications.
>
> A quick test seems to contradict this. "private" appears to be "private".

Which javac and jvm? Or was it statically compiled code with gcj? I
expect the latter especially might differ in implementation.

What test case did you use? I'd suggest

package test;

public class AccessTester1 {
    private int foo;

    public AccessTester1 (int x) { foo = x; }
    public class FooRetriever {
        public int getOuterFoo() { return foo; }
    }
    public FooRetriever getFooRetriever () { return new FooRetriever(); }
}

package test;

public class AccessTester2 {
    public static void main (String[] args) {
        AccessTester1 a = new AccessTester1(3);
        AccessTester1.FooRetriever fr = a.getFooRetriever();
        System.out.println(""+fr.getOuterFoo()); // 3
        System.out.println(""+a.foo); // Compile error
    }
}

This pair should have AccessTester2 fail to compile. Change "private int
foo;" to "int foo;" in AccessTester1 and compile both to get a working
class pair. Change back to "private int foo;" in AccessTester1 and
recompile it only (obviously don't use Eclipse or anything else that
updates everything else automatically!) and run it. It should work.
Remove FooRetriever and change getFooRetriever to int getFoo() (and
change AccessTester2 to replace the 2nd and 3rd lines of main with
"System.out.println(""+a.getFoo());") and it won't compile. Change foo's
declaration to just "int foo;" and it will, and everything works. Now
change it back without recompiling AccessTester2 and AccessTester1
should compile, but AccessTester2 should print "3" and then bomb at
runtime with an access exception of some sort because foo is private.

The *compiler* seems to treat "private" as "private", but the *runtime*
seems to treat it as "package private" when there's an inner class that
accesses the member.

Try also changing FooRetriever to return zero rather than access foo
rather than remove it entirely.

Some of this behavior is probably quite implementation-dependent, but
the failure to throw exceptions at run-time when the private member is
accessed is troubling. Besides security implications, the example above
demonstrates changing semantics for one class when the private
implementation of another is fiddled with, instead of attempted access
to said private implementation always failing in a consistent way. When
code from different sources (e.g. application code and library code, or
code in collaborative efforts) get combined queer dependencies can
result, especially if one of the coders doesn't have access to the
source for some of the other code (e.g. application coder using a
closed-source library).

I guess you can also read the above as yet another argument for open source.
Chris Smith - 27 Dec 2006 03:59 GMT
> I've read somewhere that inner class access to a "private" member of a
> nesting class causes it to be silently treated as "package-private" by
> the compiler, with security implications.

What actually happens is that the compiler generates access methods,
using the $ character in the names, to allow the access.  So yes, if you
are relying on access specifiers to enforce security conditions via the
Java security architecture (i.e., SecurityManager and Permission and
related classes), you should treat things as if the variable had package
access.

Specifically, what that means is that whenever you have code that
explicitly gains additional privileges via AccessController's
doPrivileged methods, you should write that code AND all code that
performs security checks for the operation inside of a sealed package,
so that the unprivileged code cannot add classes to the same package and
subvert the access control.

> Silently changing the semantics of a security-influencing construct in
> the language strikes me as bad form.

The idea is that the distinction between private and package access is
not significant for security, because code that changes the security
context should always be located in a sealed package.

> The idea that occurred to me is a new access modifier, besides
> "private", "public", and "protected". The new modifier would grant
> access to inner classes but not to subclasses, and not to other classes
> in the same package -- only to ones nested in the correct parent class.

The goal of the current implementation was to minimize the impact of
language changes; specifically, to avoid major changes to the class file
format.  Adding a new access modifier like that would affect not only
the VM (significant parts of which are still not aware of the existence
of nested classes), but would change the language as well.  It's
unlikely to go over well.

> So it needs a new name (though allowing "package" as an explicit
> access-modifier is something I'd also support, while leaving it the
> default access as well).

Yes, I'd certainly agree with your parenthetical comment.  I don't see
how it could cause any problems in parsing or ambiguity, since one could
immediately distinguish the intended usage by looking at whether we're
inside a class or not.  So who will write the RFE?

> Or, I suppose, someone could find a way to make a package secure against
> the injection of a hostile class.

Yes, that's what sealing packages does.  It already exists.  In fact,
your next paragraph (which I've snipped) pretty much describes package
sealing to the tee, including using a cryptographic signature to ensure
that the JAR file has not been modified.

Signature

Chris Smith

Chris Smith - 27 Dec 2006 04:37 GMT
> What actually happens is that the compiler generates access methods,
> using the $ character in the names, to allow the access.

And checking with both javap and "strings" on a sample class file, it
appears that this is no longer the case.  In any event, it was true at
some point in the past.  Apparently things have now been fixed so that a
class file attribute called "InnerClasses" is used during access
checking.  So there; nothing to worry about.  (You should still seal any
packages used for security, because other developers generally expect
it, and they may use package access for something they intend to
protect).

Signature

Chris Smith

jupiter - 27 Dec 2006 04:10 GMT
> I've read somewhere that inner class access to a "private" member
> of a nesting class causes it to be silently treated as
> "package-private" by the compiler, with security implications.

John, I have (below) a case that I think fits your description.
Does it?  I'm not sure what the rule is there.

package offshore.laundering.secrets;

class HaveSecrets {

  private double secretNumber = 0.0; //please do not give this to
package programmers.

    public HaveSecrets() {
      secretNumber = 23428347876.44;
  }

/* nested class with access to private outer class member. */
class NestedHaveSecrets {
    double getSecretNumber() { //This is where the WantSecrets
class has some access, but it's to a private member.
     return secretNumber;
 }
}
}
.............................................

package offshore.laundering.secrets;

/* Uses access to inner class to retrieve private member value. */
public class WantSecrets {

public static void main(String[] args) {
 HaveSecrets haveSecrets = new HaveSecrets();
 HaveSecrets.NestedHaveSecrets haveNestedSecrets = haveSecrets.new
NestedHaveSecrets();
 double gotSecret = haveNestedSecrets.getSecretNumber();

 System.out.println("Got filthy secrets=" + gotSecret);// yes,
this returns the filthy secret.  Should it?  Does this represent
the problem you mentioned?

}
}
John W. Kennedy - 27 Dec 2006 04:29 GMT
>> I've read somewhere that inner class access to a "private" member
>> of a nesting class causes it to be silently treated as
[quoted text clipped - 41 lines]
>  }
> }

What you are describing is documented behavior. The question is whether
a third class can access it from outside. The compiler definitely won't
allow that, but it may be achievable at runtime.

Signature

John W. Kennedy
"The blind rulers of Logres
Nourished the land on a fallacy of rational virtue."
  -- Charles Williams.  "Taliessin through Logres: Prelude"

John Ersatznom - 27 Dec 2006 07:45 GMT
> What you are describing is documented behavior. The question is whether
> a third class can access it from outside. The compiler definitely won't
> allow that, but it may be achievable at runtime.

My latest tests show that with the 1.6 JVM and JRE it is not. An earlier
one definitely let WantSecrets access NestedHaveSecrets if the latter
were made "private", and maybe directly the private member as well.
Certainly if the private member had a package-private accessor (at
run-time) and you had a hex editor you could hack an access of that
field into WantSecrets.class, even if NestedHaveSecrets was private and
not accessible ...
jupiter - 27 Dec 2006 23:22 GMT
> What you are describing is documented behavior. The question is
> whether a third class can access it from outside. The compiler
> definitely won't allow that, but it may be achievable at runtime.

Achievable at runtime you say?  I think I'm in the wrong era.  Do
you guys have an Andy Of Mayberry thread or something?
Thomas Hawtin - 27 Dec 2006 17:37 GMT
> I've read somewhere that inner class access to a "private" member of a
> nesting class causes it to be silently treated as "package-private" by
> the compiler, with security implications.

The basic unit of mobile code security in Java is the package (not to be
mixed up with a 'namespace'). Don't be confused by individual signatures
for class files.

Any given ClassLoader will load into a single package only classes that
are signed with the same certificate (or only unsigned classes). Classes
with the same package name loaded by different ClassLoaders, even with a
parent-child relationship, will not have package access to one another.

So if I sign my package, you cannot get your classes in without
stripping off the signature.

The documentation for a lot of this isn't to great. Published books and
articles (most of which copy one another) are largely inaccurate. If you
do find a workable way the security, the relevant contact details for
reporting the issue are here:

http://sunsolve.sun.com/pub-cgi/show.pl?target=security/sec

Tom Hawtin
Signature

http://jroller.com/page/tackline?catname=Security

Ed - 30 Dec 2006 22:40 GMT
Thomas Hawtin skrev:

> The basic unit of mobile code security in Java is the package (not to be
> mixed up with a 'namespace').
snip
> Tom Hawtin
> --
> http://jroller.com/page/tackline?catname=Security

Hej, Thomas. Going OT, could you elaborate? What are the differences
between a Java package and a namespace (ignoring the security thread)?
I presume you'll identify that Java packages are only named
hierarchically and that this hierarchy has no programatic basis - but I
just want to be sure I haven't missed something.

Thanks,

.ed

--

www.EdmundKirwan.com - Home of The Fractal Class Composition
EJP - 28 Dec 2006 03:41 GMT
> I've read somewhere that inner class access to a "private" member of a
> nesting class causes it to be silently treated as "package-private" by
> the compiler, with security implications.

Only for that access. It doesn't change the general view of the private
member from the outside.

> Silently changing the semantics of a security-influencing construct in
> the language strikes me as bad form.

It doesn't do that.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.