| By Xiaozhong Wang | Article Rating: |
|
| October 29, 2005 01:00 PM EDT | Reads: |
31,839 |
For various reasons, an application may install a security manager. Usually it does so to guard against malicious third-party code either installed or dynamically downloaded at runtime. If the application uses RMI APIs, it's even required by a Java specification that a security manager be installed, otherwise the classloader will not download any classes from remote locations.
The most convenient security manager to use is java.lang.SecurityManager. Once installed, it will work with security policy to control the security permissions granted to different protection domains. For simplicity, it will be referred to as SecurityManager for the rest of this article.
The security policy is statically initialized at application start-up. For Sun's JDK, the security policy is defined in a security policy file. Naturally, this initial security policy cannot be changed at runtime once it's loaded with the application.
What if you want the security permissions to change at runtime? For example, you have a list of hosts from which the socket connection requests should not be accepted by the security manager. This list keeps changing when the application is running and you don't want to shut the application down to make the latest list effective. Or you feel that the expressions allowed in the security policy file are not enough for your application. Sure, it allows wildcards like "*", but you need something more dynamic and powerful, like a regular expression. What can you do?
Before any solution is proposed, let's take a look at how security permissions are managed normally. First, create a security policy that defines a set of security permissions granted to one or more protection domains, then install java.lang.SecurityManager at the start of your application. When the application calls a security-sensitive API, the API first checks with the SecurityManager to determine whether certain operations are allowed. The SecurityManager calls AccessContoller.checkPermission() method, which in turn consults the security policy when making security permission decisions.
It's not difficult to find out from the above that three components work together to provide security permissions - a security manager, a security policy, and the AccessContoller. AccessController is a final class and cannot be dynamically set with the system, so there's nothing we can do about it. SecurityManager and Policy, on the other hand, are extendable and can be set with the system.
It seems there are two approaches - writing your own security manager or writing your own security policy.
Writing Your Own Security Manager
If you take a look at SecurityManager APIs, the bulk of them are two checkPermission() methods and some checkOperation() methods, where Operation is an action like Connect, Listen, SetFactory, etc. If the security permission is granted, these methods simply return without doing anything. Otherwise, they throw SecurityException to indicate that the related security permission is denied. To dynamically control the behavior, just override one or more such APIs. If a method is not overridden, leave the behavior to SecurityManager and essentially the security policy to decide.
So far this seems easy. Is that so? Let's find out with a simple example. In this example, you want to control which properties can be accessed by overriding the checkPropertyAccess(String key) API. It's assumed that the list of accessible properties keeps changing and you get a fresh list each time checkPropertyAccess(String key) is invoked (see Listing 1).
You don't expect to get a security exception because we allow access to "user.home". By the way, if you use a security policy file that grants PropertyPermission to access "user.home" and "user.dir" and install a SecurityManager, TestProperty prints out the value of "user.home" just as expected.
If you run TestProperty with MySecurityManager in Sun's JDK 1.4.2, it prints out the following:
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.lang.SecurityException: Not allowed!
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
The exception is thrown from System.setSecurityManager() and is caused by a read of property "su.net.inetaddr.ttl", which is totally unrelated to our code. Seems like you just shot yourself in the foot, yet you don't know where the bullet came from.
Actually it's not important to know where the check comes from, but it is important to note that the security exception is caused by an AccessController.doPrivileged() call.
When we try the TestProperty application with the standard SecurityManager and security policy, AccessController.doPrivileged doesn't throw a security exception. This is because SecurityManager.checkPropertyAccess() delegates to checkPermission(), which in turn calls AccessController.checkPermission(). AccessController knows how to handle privileged code blocks. When it sees a privileged code block and the associated protection domain has the required permission, it returns without further checking callers of the privileged code block on the call stack. In our case, the privileged code block is in the sun.net.InetAddressCachePolicy, which is from the system domain that has all the permissions.
Let's go back to MySecurityManager. There is no way for it to know whether a call is from a privileged code block or the information about the call stack. It grants and denies the same set of permissions to all protection domains, even if the protection domain is the system domain where all permissions should be granted. That's where the problem comes from.
For more details regarding AccessController, I encourage you to check out the JavaDoc for the AccessController and security documentation at http://java.sun.com/j2se/1.4.2/docs/guide/security/ spec/security-spec.doc4.html#20389.
It's important to note that MySecurityManager tends to be more restrictive than SecurityManager (or the initial security policy) by specifically disallowing access to most of the properties. On the other hand, an application may need a security manager that is less restrictive than the initial security policy at certain times. In this case, override a SecurityManager's check method in the following manner:
- Specifically allow an action by directly returning from the method when a condition is met.
- Otherwise delegate to the same checkOperation() method in its super class to get the default behavior controlled by the initial security policy.
Published October 29, 2005 Reads 31,839
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.
- Cloud Expo New York | Danger Ahead: Why File Sync Is NOT Endpoint Backup
- Cloud Expo New York: Aligning Your Cloud Security with the Business
- Overview of the OpenStack Cloud
- Session Topics: 12th Cloud Expo / Cloud Expo New York
- Cloud Expo New York: Managing Legal Risks in Cloud Computing
- Cloud Expo NY: Best Practices for Architecting Your Cloud Infrastructure
- Cloud Expo NY: Environmental Pressures Drive an Evolution in File Storage
- Apple’s Key Rubber-Band Patent Found Invalid Again
- Is Cloud Safer Than Your Traditional Datacenter?
- NIST to Sponsor FFRDC Widespread Adoption of Integrated CyberSecurity
- Cloud Expo New York: Anatomy of an Internet Scale Application
- Cloud Expo NY: Accelerating Cloud Computing with Intel SSD Technology
- Cloud Expo New York Speaker Profile: Jill T. Singer – NRO
- Cloud Expo New York | CEO Insider: Overcoming Cloud Barriers
- Cloud Expo New York | Danger Ahead: Why File Sync Is NOT Endpoint Backup
- SAML Finds Its Cloud Legs
- Cloud Expo New York: Aligning Your Cloud Security with the Business
- Overview of the OpenStack Cloud
- Session Topics: 12th Cloud Expo / Cloud Expo New York
- Cloud Expo New York: Managing Legal Risks in Cloud Computing
- Cloud Expo NY: Best Practices for Architecting Your Cloud Infrastructure
- Five Steps Toward Achieving Better Compliance with Identity Analytics
- Development Testing for Java Applications
- Cloud Expo NY: The Promise of an End-to-End SDN Solution - Can It Be Done?
- Effective Page Authorization In JavaServer Faces
- The Top 250 Players in the Cloud Computing Ecosystem
- Cloud Expo New York Call for Papers Now Open
- SOA Focus - Web Services Security in Java EE
- IBM Security Report Predicts Mobile/Satellite Attacks in 2005
- Industry Experts Discuss the State of Cloud Computing
- The Cloud Computing Kettle Heats Right Up
- The Top 100 Bloggers on Cloud Computing
- The Next Chapter in the Virtualization Story Begins
- Java Application Security in the Corporate World
- ColdFusion Security Best Practices
- Cloud Expo 2011 East To Attract 10,000 Delegates and 200 Exhibitors
























