T
Twisted
As security-conscious Java programmers surely know, package-private
access doesn't stop untrusted code having access -- anyone, including
Joe Cracker, can make a class and define it in *your* package.
But this could be changed. Here's how:
* A "closed package" would have a certain format to its name, such that
the name started with
a string that could be converted into a fairly large integer + check
digits and validated with
some sort of CRC check; then a dot and arbitrary further characters.
Any package name
meeting this description (i.e. the first word, dot-delimited, when
decoded in the appropriate
manner, passes its validation check) would be closed. The scheme
would be designed so that
ordinary words would not tend to pass the check (a rare but legal
identifier character, say,
might be always present). Accidentally creating closed packages would
therefore be easily
avoidable. The CRC check/whatever would serve this purpose, not a
security purpose.
* The VM would balk at loading any class defined in a closed package
unless it met an
authentication check.
* The authentication check would consist in extracting/obtaining a
signature chunk from/relating
to the class, decoding it using the integer obtained from the package
name above as a public
key, and comparing against a SHA-1 (or even stronger hash) of the
class.
Then no class would be loaded into a closed package that wasn't signed
by whoever named the package. Knowing the name of the package gives
someone only the public of a key-pair, so does not enable Joe Cracker
to introduce a hostile class thereto; altering an existing class binary
or recompiling from modified source would likewise change the hash and
invalidate the signature. The signature would prove, then, that *the
specific binary loaded* by the VM was authorized by the package "owner"
(whoever generated the key pair, and then the package name from the
public key of the pair), or at least knew the private key.
Note that the signature would not necessarily have to be part of the
..class file. It could be loaded off a Web site, authentication server,
or whatever seems appropriate. It could come from an untrusted source;
the worst they could do by altering/spoofing signatures without knowing
the private key is disable some classes in protected packages. This
might enable a denial of service attack, of course, so having multiple
and/or local signature info and accepting a class if you accept any
signature for it might make sense.
Runtime .class generation into, or alteration of classes in, closed
packages might need to be disallowed (VM balks), or limited to being
done by classes already in the package. Subpackages (i.e., given
package.this.that, foo.package.this.that) already don't have privileged
access to package private members, and so aren't a security risk here.
Of course, the proposed scheme would break the "com.foo.bar"
reversed-hostname package naming convention, but could be altered to
suit. Or we could dispense with that convention. I'm not a big fan of
it anyway, since it implicitly discriminates against anyone who can't
afford to pay a premium for their own personal domain name on top of
whatever they already pay for internet access (not to think of people
with NO NET ACCESS AT ALL) ... and therefore a lot of individual,
garage-band, and FOSS developers. (I don't know what a .com domain goes
for currently, but I do know it's a recurring fee rather than one-time,
and I also know that if it's so much as one red cent plus the need to
go out and sign up with a CC company to have a CC# to put in some Web
form somewhere so that the next CD Universe type event will expose me
to a risk of identity theft, then it is one red cent more than I am
willing to pay for the ability to follow this naming convention -- so
sue me.)
access doesn't stop untrusted code having access -- anyone, including
Joe Cracker, can make a class and define it in *your* package.
But this could be changed. Here's how:
* A "closed package" would have a certain format to its name, such that
the name started with
a string that could be converted into a fairly large integer + check
digits and validated with
some sort of CRC check; then a dot and arbitrary further characters.
Any package name
meeting this description (i.e. the first word, dot-delimited, when
decoded in the appropriate
manner, passes its validation check) would be closed. The scheme
would be designed so that
ordinary words would not tend to pass the check (a rare but legal
identifier character, say,
might be always present). Accidentally creating closed packages would
therefore be easily
avoidable. The CRC check/whatever would serve this purpose, not a
security purpose.
* The VM would balk at loading any class defined in a closed package
unless it met an
authentication check.
* The authentication check would consist in extracting/obtaining a
signature chunk from/relating
to the class, decoding it using the integer obtained from the package
name above as a public
key, and comparing against a SHA-1 (or even stronger hash) of the
class.
Then no class would be loaded into a closed package that wasn't signed
by whoever named the package. Knowing the name of the package gives
someone only the public of a key-pair, so does not enable Joe Cracker
to introduce a hostile class thereto; altering an existing class binary
or recompiling from modified source would likewise change the hash and
invalidate the signature. The signature would prove, then, that *the
specific binary loaded* by the VM was authorized by the package "owner"
(whoever generated the key pair, and then the package name from the
public key of the pair), or at least knew the private key.
Note that the signature would not necessarily have to be part of the
..class file. It could be loaded off a Web site, authentication server,
or whatever seems appropriate. It could come from an untrusted source;
the worst they could do by altering/spoofing signatures without knowing
the private key is disable some classes in protected packages. This
might enable a denial of service attack, of course, so having multiple
and/or local signature info and accepting a class if you accept any
signature for it might make sense.
Runtime .class generation into, or alteration of classes in, closed
packages might need to be disallowed (VM balks), or limited to being
done by classes already in the package. Subpackages (i.e., given
package.this.that, foo.package.this.that) already don't have privileged
access to package private members, and so aren't a security risk here.
Of course, the proposed scheme would break the "com.foo.bar"
reversed-hostname package naming convention, but could be altered to
suit. Or we could dispense with that convention. I'm not a big fan of
it anyway, since it implicitly discriminates against anyone who can't
afford to pay a premium for their own personal domain name on top of
whatever they already pay for internet access (not to think of people
with NO NET ACCESS AT ALL) ... and therefore a lot of individual,
garage-band, and FOSS developers. (I don't know what a .com domain goes
for currently, but I do know it's a recurring fee rather than one-time,
and I also know that if it's so much as one red cent plus the need to
go out and sign up with a CC company to have a CC# to put in some Web
form somewhere so that the next CD Universe type event will expose me
to a risk of identity theft, then it is one red cent more than I am
willing to pay for the ability to follow this naming convention -- so
sue me.)