First and foremost, we highly recommend analyzing
all your custom security
manager methods before running your security manager under
the Java 2 SDK. Failure
to do so could result in a security hole or prevent the proper
operation of the SDK. This is due to the fragile
nature of 1.1-style security managers.
Where possible, you should just use the default implementation of
the 1.2 SecurityManager
. This helps give users and
administrators consistent behavior. If this is not possible, then
you should at least try to call super.checkXXX
in your checkXXX
method before throwing a security
exception. Doing so will allow the access controller algorithm
to be used, and will allow the SDK itself to function correctly.
In the Java 2 SDK, any existing code that used to call any of the
SecurityManager check
methods continues to do so.
For new code that requires a security check, calls are made
to SecurityManager.checkPermission
instead of adding
a new SecurityManager check
method. For example, the
new java.lang.System.setProperty
method calls
checkPermission
with a java.util.PropertyPermission
permission.
When extending the SecurityManager class and overriding
existing methods, some care should be taken. For example, if you override
the checkRead(String file)
method so it always throws a
security exception, then the SDK itself may fail to operate properly.
That is, if some SDK code needs to open a file (to read a properties
file, load a JAR file, etc.) then throwing a security exception for every
read attempt would cause such opens to always fail.
In general, you
should only override the default methods if you intend to loosen
security, not to make it stronger.
If you want to tighten security,
you should modify the default policy files and/or install a
custom java.security.Policy
object. See the security
guide on
policy files for more information.
In general, when overriding security manager methods you should place
a call to the super.checkXXX
method at the point where your
overridden checkXXX
method would throw an exception.
For example:
public class MySecurityManager extends SecurityManager {
public void checkRead(String file) {
if (someCustomSecurityCheckFails()) {
super.checkRead(file);
}
}
}
If your custom security check fails, then super.checkRead
gets
called. The default implementation of checkRead
invokes
checkPermission
, which by default consults the
AccessController
. By invoking the AccessController
,
system code that has done an AccessController.doPrivileged
before
trying to read a file will succeed in reading that file. All other code
will be subjected to the current policy in effect, and an access control
exception will be thrown if access to that file has not been granted.
Note, there are some checkXXX
methods in which you should
not call super.checkXXX
methods when overriding them. That
is because the default implementation of these methods may not be
as strict as the policy you are implementing in the overridden method.
For example, the default checkAccess(ThreadGroup g)
method
only protects the system thread group. If you intend to
protect threads in distinct thread groups from each other (for example
applet thread groups), then you would not want to call
super.checkAccess
at the point you would normally throw
a security exception, as that would defeat the purpose of your customized
check. Instead, you could place a call to super.checkAccess
as the first statement in your overridden method.
For example:
public class AppletSecurityManager extends SecurityManager {
public void checkAccess(ThreadGroup g) {
// a call to super will throw an exception if someone
// is trying to modify the system thread group
super.checkAccess(g);
...
// now perform checks based on which applet thread group
// the current caller is in to see if they can modify thread group g.
...
}
We describe how to override each method in the following section.
This section lists changes made to java.lang.SecurityManager
methods in the Java 2 SDK and provides suggestions regarding any overrides you
may wish to make. Please see the Java documentation for the
SecurityManager
class
for more information on these methods.
protected boolean inCheck
This field has been deprecated, and any uses of this field within
the SDK itself have been removed. Instead of using inCheck, you should
use checkPermission
along with doPrivileged
.
public boolean getInCheck();
This method has also been deprecated.
public SecurityManager();
The constructor has been modified to allow multiple SecurityManagers
to be created, assuming the caller has the
RuntimePermission("createSecurityManager")
permission.
protected native Class[] getClassContext();
No changes. This call can be used to emulate the 1.1 behavior
of the methods that have been changed in the Java 2 SDK (
currentClassLoader
, currentLoadedClass
,
classLoaderDepth
, inClassLoader
).
protected ClassLoader currentClassLoader();
The typical use of this method in JDK 1.1-style security managers
was to see if there was a class loader on the stack, and if not,
treat the code as "trusted" and allow it to do anything. This
method has been modified in the Java 2 SDK to allow trusted SDK code
(actually any code granted java.security.AllPermission
)
that calls doPrivileged
to be treated as trusted
by 1.1-style security managers. It has also been modified to
skip system class loaders. A system class loader is defined as being
a class loader that is equal to the system class loader (as returned
by ClassLoader.getSystemClassLoader) or one of its ancestors.
This method will return
null
in the following three cases:
- All methods on the execution stack are from classes
defined using the system class loader or one of its ancestors.
- All methods on the execution stack up to the first
"privileged" caller
(see java.security.AccessController.doPrivileged)
are from classes
defined using the system class loader or one of its ancestors.
- A call to checkPermission with
java.security.AllPermission
does not
result in a SecurityException.
This method has been deprecated. Use checkPermission
instead.
protected Class currentLoadedClass();
This method has been modified in the same fashion as
currentClassLoader
, and will return null
if the current security context has been granted
AllPermission
or all the methods on the stack
(up to the first privileged caller, if any) are from
classes defined using the system class loader or one of its
ancestors.
This method has been deprecated. Use checkPermission
instead.
protected int classDepth(String name);
No changes in behavior. This method has been deprecated.
Use checkPermission
instead.
protected int classLoaderDepth();
This method has been modified in the same fashion as
currentClassLoader
, and will return -1
if the current security context has been granted
AllPermission
or all the methods on the stack
(up to the first privileged caller, if any) are from
classes defined using the system class loader or one of its
ancestors.
This method has been deprecated. Use checkPermission
instead.
protected boolean inClass(String name);
No changes in behavior. This method has been deprecated.
Use checkPermission
instead.
protected boolean inClassLoader();
This method returns true if currentClassLoader
returns a non-null class loader, so it follows the same
semantics that currentClassLoader
does.
This method has been deprecated. Use checkPermission
instead.
public Object getSecurityContext();
This method returns a
java.security.AccessControlContext
object that is
created with a call to
java.security.AccessController.getContext
. In JDK1.1
it returned null
by default.
public void checkPermission(Permission perm);
This method is new in the Java 2 SDK. It calls
java.security.AccessController.checkPermission
with the given permission. Internally, the SDK always
calls SecurityManager.checkPermission
instead
of calling the AccessController
directly. This
allows people to override this method to provide additional
functionality such as auditing and/or GUI dialogs.
public void checkPermission(Permission perm, Object context);
This method is new in the Java 2 SDK. If context
is an
instance of
AccessControlContext
then the
AccessControlContext.checkPermission
method will
be invoked on the given context with the specified permission.
If context
is not an instance of
AccessControlContext
then a
SecurityException
is thrown.
public void checkCreateClassLoader();
This method has been modified to call checkPermission
with the RuntimePermission("createClassLoader")
permission.
If this method is overridden, then a call to
super.checkCreateClassLoader
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkCreateClassLoader() {
if (someCustomSecurityCheckFails()) {
super.checkCreateClassLoader();
}
}
}
public void checkAccess(Thread t);
If the thread argument is a system thread (belongs to
the thread group with a null
parent) then
this method calls checkPermission
with the
RuntimePermission("modifyThread")
permission.
Applications that want a stricter policy should override this
method.
If this method is overridden, then super.checkAccess
should
be called by the first statement in the overridden method, or the equivalent
security check should be placed in the overridden method.
If this method is overridden, the method that overrides
it should additionally check to see if the calling thread has the
RuntimePermission("modifyThread")
permission, and
if so, return silently. This is to ensure that code granted
that permission (such as the SDK itself) is allowed to
manipulate any thread.
For example:
public class MySecurityManager extends SecurityManager {
public void checkAccess(Thread t) {
// a call to super will throw an exception if someone
// is trying to modify a system thread
super.checkAccess(t);
...
if (someCustomSecurityCheckForOtherThreadsFails()) {
// if the check fails, instead of throwing an exception,
// call checkPermission, which will throw an exception
// if need be
checkPermission(new RuntimePermission("modifyThread"));
}
...
}
}
public void checkAccess(ThreadGroup g);
If the thread group argument is the system thread group
(has a null
parent) then
this method calls checkPermission
with the
RuntimePermission("modifyThreadGroup")
permission.
Applications that want a stricter policy should override this
method.
If this method is overridden, then super.checkAccess
should
be called by the first statement in the overridden method, or the
equivalent
security check should be placed in the overridden method.
If this method is overridden, the method that overrides
it should additionally check to see if the caller has the
RuntimePermission("modifyThreadGroup")
permission, and
if so, return silently. This is to ensure that code granted
that permission (such as the SDK itself) is allowed to
manipulate any thread group.
For example:
public class MySecurityManager extends SecurityManager {
public void checkAccess(ThreadGroup g) {
// a call to super will throw an exception if someone
// is trying to modify the system thread group
super.checkAccess(g);
...
if (someCustomSecurityCheckForOtherThreadGroupsFails()) {
// if the check fails, instead of throwing an exception,
// call checkPermission, which will throw an exception
// if need be
checkPermission(new RuntimePermission("modifyThreadGroup"));
}
...
}
}
public void checkExit(int status);
This method has been modified to call
checkPermission
with the
RuntimePermission("exitVM")
permission.
If this method is overridden, then a call to
super.checkExit
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkExit(int status) {
if (someCustomSecurityCheckFails()) {
super.checkExit(status);
}
}
}
public void checkExec(String cmd);
This method has been modified to call checkPermission
with a FilePermission
. If the cmd
is
an absolute path (see java.io.File.isAbsolute
) then
it is passed as-is as the target for the FilePermission
.
If cmd
is not absolute, then the special target
"<<ALL FILES>>" is used. This target is used because it is
difficult to determine the actual path of the command that will
be executed on an individual platform due to things such
as environment variables, etc.
If this method is overridden, then a call to
super.checkExec
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkExec(String cmd) {
if (someCustomSecurityCheckFails()) {
super.checkExec(cmd);
}
}
}
public void checkLink(String lib);
This method has been modified to call checkPermission
with the RuntimePermission("loadLibrary."+lib)
permission.
If this method is overridden, then a call to
super.checkLink
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkLink(String lib) {
if (someCustomSecurityCheckFails()) {
super.checkLink(lib);
}
}
}
public void checkRead(FileDescriptor fd);
This method has been modified to call checkPermission
with the RuntimePermission("readFileDescriptor")
permission.
If this method is overridden, then a call to
super.checkRead
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkRead(FileDescriptor fd) {
if (someCustomSecurityCheckFails()) {
super.checkRead(fd);
}
}
}
public void checkRead(String file);
This method has been modified to call checkPermission
with the FilePermission(file,"read")
permission.
If this method is overridden, then a call to
super.checkRead
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkRead(String file) {
if (someCustomSecurityCheckFails()) {
super.checkRead(file);
}
}
}
public void checkRead(String file, Object context);
This method has been modified. If context
is an instance of AccessControlContext
then the
AccessControlContext.checkPermission
method will
be invoked on the given context with the
FilePermission(file,"read")
permission.
If context
is not an instance of
AccessControlContext
then a
SecurityException
is thrown.
If this method is overridden, then a call to
super.checkRead
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkRead(String file, Object context) {
if (someCustomSecurityCheckFails()) {
super.checkRead(file, context);
}
}
}
public void checkWrite(FileDescriptor fd);
This method has been modified to call checkPermission
with the RuntimePermission("writeFileDescriptor")
permission.
If this method is overridden, then a call to
super.checkWrite
should be made
at the point the overridden method would normally throw an
exception. For Example:
public class MySecurityManager extends SecurityManager {
public void checkWrite(FileDescriptor fd) {
if (someCustomSecurityCheckFails()) {
super.checkWrite(fd);
}
}
}
public void checkWrite(String file);
This method has been modified to call checkPermission
with the FilePermission(file,"write")
permission.
If this method is overridden, then a call to
super.checkWrite
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkWrite(String file) {
if (someCustomSecurityCheckFails()) {
super.checkWrite(file);
}
}
}
public void checkDelete(String file);
This method has been modified to call checkPermission
with the FilePermission(file,"delete")
permission.
If this method is overridden, then a call to
super.checkDelete
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkDelete(String file) {
if (someCustomSecurityCheckFails()) {
super.checkDelete(file);
}
}
}
public void checkConnect(String host, int port);
This method has been modified to call checkPermission
with the SocketPermission(host+":"+port,"connect")
permission if the port is not equal to -1. If the port is equal
to -1, then it calls checkPermission
with the
SocketPermission(host,"resolve")
permission.
This behavior is consistent with JDK 1.1, where a port equal to
-1 indicates that an IP address lookup is being performed.
If this method is overridden, then a call to
super.checkConnect
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkConnect(String host, int port) {
if (someCustomSecurityCheckFails()) {
super.checkConnect(host, port);
}
}
}
public void checkConnect(String host, int port, Object context);
This method has been modified.
If context
is an instance of
AccessControlContext
then the
AccessControlContext.checkPermission
method will
be invoked on the given context with the
SocketPermission(host+":"+port,"connect")
permission if
the port is not equal to -1. If the port is equal to -1, then
it calls checkPermission
with the
SocketPermission(host,"resolve")
permission.
If context
is not an instance of
AccessControlContext
then a
SecurityException
is thrown.
If this method is overridden, then a call to
super.checkConnect
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkConnect(String host, int port, Object context) {
if (someCustomSecurityCheckFails()) {
super.checkConnect(host, port, context);
}
}
}
public void checkListen(int port)
This method has been modified.
If port is not 0, it calls
checkPermission
with the
SocketPermission("localhost:"+port,"listen")
.
If port is zero, it calls checkPermission
with SocketPermission("localhost:1024-","listen").
If this method is overridden, then a call to
super.checkListen
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkListen(int port) {
if (someCustomSecurityCheckFails()) {
super.checkListen(port);
}
}
}
public void checkAccept(String host, int port);
This method has been modified to call checkPermission
with the SocketPermission(host+":"+port,"accept")
permission.
If this method is overridden, then a call to
super.checkAccept
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkAccept(String host, int port) {
if (someCustomSecurityCheckFails()) {
super.checkAccept(host, port);
}
}
}
public void checkMulticast(InetAddress maddr);
This method has been modified to call checkPermission
with the
SocketPermission(maddr.getHostAddress(),"accept,connect")
permission.
If this method is overridden, then a call to
super.checkMulticast
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkMultiCast(InetAddress maddr) {
if (someCustomSecurityCheckFails()) {
super.checkMultiCast(maddr);
}
}
}
public void checkMulticast(InetAddress maddr, byte ttl);
This method has been modified to call checkPermission
with the
SocketPermission(maddr.getHostAddress(),"accept,connect")
permission.
If this method is overridden, then a call to
super.checkMulticast
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkMultiCast(InetAddress maddr, byte ttl) {
if (someCustomSecurityCheckFails()) {
super.checkMultiCast(maddr, ttl);
}
}
}
public void checkPropertiesAccess();
This method has been modified to call checkPermission
with the PropertyPermission("*", "read,write")
permission.
If this method is overridden, then a call to
super.checkPropertiesAccess
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkPropertiesAccess() {
if (someCustomSecurityCheckFails()) {
super.checkPropertiesAccess();
}
}
}
public void checkPropertyAccess(String key);
This method has been modified to call checkPermission
with the PropertyPermission(key, "read")
permission.
If this method is overridden, then a call to
super.checkPropertyAccess
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkPropertyAccess(String key) {
if (someCustomSecurityCheckFails()) {
super.checkPropertiesAccess(key);
}
}
}
public boolean checkTopLevelWindow(Object window);
This method has been modified to call
checkPermission
with the
AWTPermission("showWindowWithoutWarningBanner")
permission,
and returns true if an SecurityException is not thrown, otherwise
it returns false.
If this method is overridden, then a call to
super.checkTopLevelWindow
should be made
at the point the overridden method would normally return false,
and the value of super.checkTopLevelWindow
should
be returned. For example:
public class MySecurityManager extends SecurityManager {
public void checkTopLevelWindow(Object window) {
if (someCustomSecurityCheckFails()) {
return super.checkTopLevelWindow(window);
} else {
return true;
}
}
}
public void checkPrintJobAccess();
This method has been modified to call
checkPermission
with the
RuntimePermission("queuePrintJob")
permission.
If this method is overridden, then a call to
super.checkPrintJobAccess
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkPrintJobAccess() {
if (someCustomSecurityCheckFails()) {
super.checkPrintJobAccess();
}
}
}
public void checkSystemClipboardAccess();
This method has been modified to call checkPermission
with the AWTPermission("accessClipboard")
permission.
If this method is overridden, then a call to
super.checkSystemClipboardAccess
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkSystemClipboardAccess() {
if (someCustomSecurityCheckFails()) {
super.checkSystemClipboardAccess();
}
}
}
public void checkAwtEventQueueAccess();
This method has been modified to call checkPermission
with the AWTPermission("accessEventQueue")
permission.
If this method is overridden, then a call to
super.checkAwtEventQueueAccess
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkAwtEventQueueAccess() {
if (someCustomSecurityCheckFails()) {
super.checkAwtEventQueueAccess();
}
}
}
public void checkPackageAccess(String pkg);
This method has been modified. It first gets a list of
restricted packages by obtaining a comma-separated list from
a call to
java.security.Security.getProperty("package.access")
,
and checks to see if pkg
starts with or equals
any of the restricted packages. If it does, then
checkPermission
gets called with the
RuntimePermission("accessClassInPackage."+pkg)
permission.
If this method is overridden, then
super.checkPackageAccess
should be called
as the first line in the overridden method. For example:
public class MySecurityManager extends SecurityManager {
public void checkPackageAccess(String pkg) {
super.checkPackageAccess(pkg);
...
someCustomSecurityCheck();
...
}
}
public void checkPackageDefinition(String pkg);
This method has been modified. It first gets a list of
restricted packages by
obtaining a comma-separated list from a call to
java.security.Security.getProperty("package.definition")
,
and checks to see if pkg
starts with or equals
any of the restricted packages. If it does, then
checkPermission
gets called with the
RuntimePermission("defineClassInPackage."+pkg)
permission.
If this method is overridden, then
super.checkPackageDefinition
should be called
as the first line in the overridden method. For example:
public class MySecurityManager extends SecurityManager {
public void checkPackageDefinition(String pkg) {
super.checkPackageDefinition(pkg);
...
someCustomSecurityCheck();
...
}
}
public void checkSetFactory();
This method has been modified to call checkPermission
with the RuntimePermission("setFactory")
permission.
If this method is overridden, then a call to
super.checkSetFactory
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkSetFactory() {
if (someCustomSecurityCheckFails()) {
super.checkSetFactory();
}
}
}
public void checkMemberAccess(Class clazz, int which);
This method has been modified. The default policy is to allow
access to PUBLIC members, as well
as access to classes that have the same class loader as the caller.
In all other cases call checkPermission
with the RuntimePermission("accessDeclaredMembers")
permission.
If this method is overridden, then a call to
super.checkMemberAccess
cannot be made,
as the default implementation of checkMemberAccess
relies on the code being checked being at a stack depth of
4. For example:
someCaller[3]
java.lang.Class.someReflectionAPI [2]
java.lang.Class.checkMemberAccess [1]
SecurityManager.checkMemberAccess [0]
In order to emulate this behavior, you would need to call
getClassContext
, and examine the class loader of
the class at index 3, just as the default
checkMemberAccess
method does:
if (which != Member.PUBLIC) {
Class stack[] = getClassContext();
/*
* stack depth of 4 should be the caller of one of the
* methods in java.lang.Class that invoke checkMember
* access. The stack should look like:
*
* someCaller [3]
* java.lang.Class.someReflectionAPI [2]
* java.lang.Class.checkMemberAccess [1]
* MySecurityManager.checkMemberAccess [0]
*
*/
if ((stack.length<4) ||
(stack[3].getClassLoader() != clazz.getClassLoader())) {
if (checkMemberAccessPermission == null)
checkMemberAccessPermission =
new RuntimePermission("accessDeclaredMembers");
checkPermission(checkMemberAccessPermission);
}
}
This is the only security manager method in the Java 2 SDK that is still based
on a caller's depth. This is to allow a caller to reflect on classes
from the same class loader it came from.
public void checkSecurityAccess(String target);
This method has been modified to create a
SecurityPermission
object for
the given permission target name and calls checkPermission
with it.
If this method is overridden, then a call to
super.checkSecurityAccess
should be made
at the point the overridden method would normally throw an
exception. For example:
public class MySecurityManager extends SecurityManager {
public void checkSecurityAccess(String target) {
if (someCustomSecurityCheckFails()) {
super.checkSecurityAccess(target);
}
}
}
public ThreadGroup getThreadGroup();
This method has not been changed.