J
John Ersatznom
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.)
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.)