|
WELCOME to the Java Developer Connection (JDC) Tech Tips, January 30, 2001. This issue of the JDC Tech Tips covers techniques for controlling access to Java packages. The topics covered are:
This tip was developed using Java 2 SDK, Standard Edition, v 1.3. This issue of the JDC Tech Tips is written by Stuart Halloway, a Java specialist at DevelopMentor (http://www.develop.com/java). CONTROLLING PACKAGE ACCESS WITH SECURITY PERMISSIONS
In the Java programming language, a package is an important
abstraction that supports object-oriented design. A package is
a group of classes that work together on some common task. For
example, the
This level of access is invaluable for implementation details that need to be shared across multiple classes, and because of that, cannot be marked "private." However, default access only provides encapsulation if you control all the code that is loaded into your package. Otherwise, developers can accidentally (or maliciously) add their own classes to your package, and gain access to all the default-access classes, methods, and fields inside of the package.
The Java platform provides several mechanisms to control package
access. Two of these are built-in permissions relating to package
access, and JAR sealing, which is supported by the
The Java security architecture defines two permission prefixes
that control the use of packages: the
In each case, the suffix of the permission name is the name of
the package. However, something is obviously missing from this
story. Most Java policy files do not have any entries like these,
yet Java applications are able to access these and other packages.
The reason for this is that packages are not secured by default.
To secure them, you must edit the
As you can see, the only packages that are access protected are those prefixed with "sun." To see the protection in action, use the following test class, which simply verifies that it can load a class from a URL:
Try running this class with the following command line (that is, all on one line):
java -Djava.security.manager
-Djava.security.policy=Test.policy
TestAccess file:someRandomURL/ sun.secret.Class
The If you run the class, you should see the following exception:
java.security.AccessControlException:
access denied
(java.lang.RuntimePermission
accessClassInPackage.sun.secret)
It does not matter what URL you use, because the security check
against the package name occurs before the class loader tries to
access the URL. To give your code permission to access the
permission java.lang.RuntimePermission
"accessClassInPackage.sun.secret";
If you retry the class with the same command line as before, you should see the more mundane error:
java.lang.ClassNotFoundException:
sun.secret.Class
Of course, had there really been a
You can use the same mechanism to protect you own package names
by adding the package prefixes to either the There are a few caveats to this technique. First, you must make sure to use class loaders that participate in this part of the security architecture. The common class loaders' implementations of package security are summarized below:
As you can see, none of the class loaders provided with the JDK
check for permission to define a class. If you want to add this
capability, you need to use a custom class loader that overrides
The other caveat has to do with editing the package.access=sun. protects "sun.misc" and "sun.tools" but it would not protect the sun package because there is no trailing period to match. But if the entry were edited to read: package.access=sun it would protect the sun package, but also other packages with names such as "sundance", "sung", and "sundry". You can read more about RuntimePermissions at http://java.sun.com/products/jdk/1.2/docs/guide/security/permissions.html#RuntimePermission CONTROLLING PACKAGE ACCESS WITH SEALED JAR FILESThe security mechanisms discussed in the tip "Controlling Package Access With Security Permissions" approach the problem at a fairly low level. Most developers do not need this level of control, and simply want to guarantee that all classes in a package come from the same code source. This common case is supported by JAR "sealing." You can seal a JAR file by specifying a true value for the sealed attribute, that is: Sealed: true Note that the default value of the sealed attribute is false. After a class loader loads a class from a sealed JAR file, classes in the same package can only be loaded from that JAR file. You can override sealing on a per-package basis with additional attributes listed after the package name. For example, you can have a main section as follows (terminated by blank line): Sealed: false And follow the main section with sub-sections that have per-entry attributes: Name: com/develop/impl/ Sealed: true
To see sealing in action, move the //place in file sealme/TestAccess.java package sealme; //repeat TestAccess.java contents from above Then, create a manifest that seals all packages. The file should have the following lines and end with a blank line: Manifest-Version: 1.0 Sealed: true Create a sealed jar file with the jar tool: jar cvmf manifest sealme.jar sealed/TestAccess.class
Now, create another class in a separate location from
package sealme;
public class LoadMe {
}
Try running
java -cp sealme.jar sealme.TestAccess file:dynclass/
sealme.LoadMe
Because the jar file is sealed, you will not be able to load
java.lang.SecurityException: sealing violation
at java.net.URLClassLoader.defineClass
(URLClassLoader.java:234)
(etc.)
Notice that package sealing works regardless of whether you have
installed a security manager. This is in marked contrast to the
It is interesting to note that the "
"[granting] this is dangerous because malicious code with this
permission may define rogue classes in trusted packages like
This is doubly wrong. First, the
Obviously Sun takes the protection of the core API packages very seriously! You should take similar care when deploying own Java packages. JAR sealing is part of the Java extensions mechanism. For more information, see http://java.sun.com/products/jdk/1.2/docs/guide/extensions/index.html Note Sun respects your online time and privacy. The Java Developer Connection mailing lists are used for internal Sun MicrosystemsTM purposes only. You have received this email because you elected to subscribe. To unsubscribe, go to the Subscriptions page (https://softwarereg.sun.com/registration/developer/en_US/subscriptions), uncheck the appropriate checkbox, and click the Update button. Subscribe To subscribe to a JDC newsletter mailing list, go to the Subscriptions page (https://softwarereg.sun.com/registration/developer/en_US/subscriptions), choose the newsletters you want to subscribe to, and click Update. Feedback Comments? Send your feedback on the JDC Tech Tips to: jdc-webmaster@sun.com Archives You'll find the JDC Tech Tips archives at: http://java.sun.com/jdc/TechTips/index.html Copyright
Copyright 2001 Sun Microsystems, Inc. All rights reserved. This document is protected by copyright. For more information, see: http://java.sun.com/jdc/copyright.html * As used in this document, the terms "Java virtual machine" or "JVM" mean a virtual machine for the Java platform. JDC Tech Tips January 30, 2001 | |||||||||||||||||||||||||
|
| ||||||||||||