| By Xiaozhong Wang | Article Rating: |
|
| October 29, 2005 01:00 PM EDT | Reads: |
26,758 |
Listing 2 is an example of a security manager that is less restrictive than SecurityManager. The nice thing about a less restrictive security manager is that it can correctly handle a privileged code block as it calls super.checkPropertyAccess(), which eventually calls AccessController.checkPermission(). But that's not the end of the story. If you use this security manager with our TestProperty application, you still get strange SecurityException:
Exception in thread "main" java.lang.ExceptionInInitializerError
at java.lang.System.setSecurityManager0(System.java:243)
at java.lang.System.setSecurityManager(System.java:212)
at TestProperty.main(TestProperty.java:5)
Caused by: java.security.AccessControlException: access denied
(java.util.PropertyPermission sun.net.inetaddr.ttl read)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:269)
at java.security.AccessController.checkPermission(AccessController.java:401)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:524)
at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1276)
at MySecurityManager.checkPropertyAccess(MySecurityManager.java:9)
at java.lang.System.getProperty(System.java:573)
at java.lang.Integer.getInteger(Integer.java:814)
at java.lang.Integer.getInteger(Integer.java:731)
at sun.security.action.GetIntegerAction.run(GetIntegerAction.java:90)
at java.security.AccessController.doPrivileged(Native Method)
at sun.net.InetAddressCachePolicy.<clinit>(InetAddressCachePolicy.java:94)
... 3 more
Guess what? On the call stack, MySecurityManager.checkPropertyAccess() is the caller of AccessController.checkPermission(). And MySecurityManager is in a protection domain that does not have all permissions like system domain does. In our case, the default security policy does not grant the required permission (java.util.PropertyPermission sun.net.inetaddr.ttl read) to MySecurityManager's protection domain. AccessController immediately throws the exception without further checking the call stack.
A quick remedy for this is to put MySecurityManager under a trusted classpath, where the classes are granted all granted permissions. In Sun's JDK, it can be achieved by using -Xbootclasspath/a: command line operation. Once this is applied, the application happily prints out the value of system property "user.home".
What have we learned? Basically there is no way to let a more restrictive security manager properly handle a privileged code block. Given that there are a lot of privileged code blocks in a Java implementation and possibly in applications, you could find a lot strange behaviors that are transparent to you under a normal security environment. It's generally not preferable to use such a security manager with your application. On the other hand, it is possible to use a less restrictive security manager with your application but not without minor deployment overhead.
Another piece of advice: checkOperation() methods are JDK 1.1 style APIs and are less preferable than checkPermission() methods, which were introduced in Java 2. According to the SecurityManager specification, all calls to checkOperation() methods delegate to checkPermission() methods with an appropriate permission object as an argument. Overriding checkPermission() will provide the same functionality as overriding checkOperation(). For simplicity, Listing 2 does not override the checkPermission() methods. This will only work if the application or the underlying Java API implementation uses checkOperation() APIs. The specification does not forbid the direct use of checkPermission() methods (in which case it makes overriding checkOperation() methods useless) in applications and new Java API implementations. Therefore, it's more efficient and much safer to override checkPermission() methods instead.
Writing Your Own Security Policy
We just mentioned that it's not preferable to use a security manager that is more restrictive than SecurityManager. But what can we do if we need more restrictive permissions? The answer: write your own security policy that extends java.security.Policy and sets it with the system. This option has become available since Sun's JDK 1.4 as it starts to support security policy set at runtime after loading the initial security policy.
Let's start by looking at the Policy specification. There are two abstract methods in Policy:
getPermissions(CodeSource codesource)
refresh()
It seems we only need to provide the implementation to these methods. However, in practice, getPermissions(ProtectionDomain domain) and implies(ProtectionDomain domain, Permission permission) should also be overridden to avoid the inconsistency caused by a particular caching strategy in a Java implementation. For example, in Sun's JDK, the implies() method sometimes returns the result from an internal cache, which may contain stale permissions granted to a particular protection domain, without calling the getPermissions() methods to get updated security permissions.
Listing 3 provides an example of a policy that provides dynamic security permissions for accessing certain properties. Please note that in order to implement getPermissions(CodeSource codesource), a customized implementation of PermissionCollection has to be available as well.
Apparently, this implementation is far more complicated than the security manager approach. However, it gives you more control of the runtime security permissions - they can be more restrictive or less restrictive than the ones specified in the initial security policy.
The application successfully prints out the property value for "user.home". If you want to print out the value for the property "user.name", it throws a SecurityException as expected:
Exception in thread "main" java.security.AccessControlException: access denied
(java.util.PropertyPermission user.name read)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:269)
at java.security.AccessController.checkPermission(AccessController.java:401)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:524)
at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1276)
at java.lang.System.getProperty(System.java:573)
at TestPolicy.main(TestPolicy.java:72)
There are two important things to note when you write your own policy:
1. Avoid using any APIs that are checked by SecurityManager in the methods of your policy implementation. In a worst case scenario, you may end up having a indefinite loop and stack overflow. If you really have to use such APIs, wrap them with a privileged code block and put your policy class under a trusted classpath.
2. Even though you have overridden all possible methods in the policy, you still can't prevent the AccessController from using the internal policy cache. One way to minimize the "bad" impact of the cache is to force a refresh of the cache by setting the policy again whenever the security permissions change. For example, you can set up a listener for the change of security permissions. When it happens, the listener takes the action to reset the policy with the system. However, if there are other threads running when the policy is reset and initialized, the threads may get incorrect security permissions from the policy simply because the policy is still in initialization. You may observe strange behaviors in your application if the security permissions change frequently.
Conclusion
To sum up, you can either override the SecurityManager or Policy to provide dynamic runtime security permissions. The security manager approach is suitable if the runtime security permissions tend to be less restrictive than the initial security policy. The security policy approach is suitable for either more restrictive or less restrictive security permissions, but you need to watch for and take extra steps to prevent unexpected behavior due to a policy cache in the underlying Java implementation. Your own policy may not work well if the security permissions change frequently for a multi-threaded application.
Published October 29, 2005 Reads 26,758
Copyright © 2005 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Xiaozhong Wang
Xiaozhong Wang is a software engineer at Sun where he has solved some security problems in his TCK (Technology Compatibility Kit) work.
- Kindle 2 vs Nook
- Why IBM’s Server Chief Got Busted
- Is Cloud Computing Like Teenage Sex?
- Industry Experts Discuss the State of Cloud Computing
- Performance Tuning Essentials for Java
- Confessions of a Ulitzer Addict
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- It's the Java vs. C++ Shootout Revisited!
- Cloud Computing Can Revitalize Your Career as Software Developer
- IBM Could "Reinvent" Java: Mills
- Oracle & Cloud Computing: Exclusive Q&A with SVP Richard Sarwal
- A Brief History of Cloud Computing
- Kindle 2 vs Nook
- Cloud CEOs, CTOs & SVPs to Speak at 4th International Cloud Computing Expo
- Why IBM’s Server Chief Got Busted
- Is Cloud Computing Like Teenage Sex?
- Industry Experts Discuss the State of Cloud Computing
- Performance Tuning Essentials for Java
- The Difference Between Web Hosting and Cloud Computing
- Cloud Computing Expo: Exclusive Q&A with Yahoo! SVP Cloud Computing
- Ajax in RichFaces 3.3, JSF 2 and RichFaces 4
- Confessions of a Ulitzer Addict
- My Thoughts on Ulitzer
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- A Cup of AJAX? Nay, Just Regular Java Please
- Java Developer's Journal Exclusive: 2006 "JDJ Editors' Choice" Awards
- The i-Technology Right Stuff
- JavaServer Faces (JSF) vs Struts
- Rich Internet Applications with Adobe Flex 2 and Java
- Java vs C++ "Shootout" Revisited
- Bean-Managed Persistence Using a Proxy List
- Reporting Made Easy with JasperReports and Hibernate
- Creating a Pet Store Application with JavaServer Faces, Spring, and Hibernate
- What's New in Eclipse?
- Why Do 'Cool Kids' Choose Ruby or PHP to Build Websites Instead of Java?
- i-Technology Predictions for 2007: Where's It All Headed?








































