I am playing around with the java .policy file and was wondering how I could go about doing something like preventing calls to java.util.Date(), as an example.
I just want to get a better sense of the .policy file works and how it can be used to sandbox code.
You'll be out of luck there I'm afraid.
As Paŭlo Ebermann says, package.access can block out package hierarchies. You can be more precise about this with a custom SecurityManager, which is usually a damn good indication you are doing something really dodgy.
In general you can make a ClassLoader that doesn't always delegate to its parent. Technically against the current Java SE spec, although the Java EE spec encourages it. You could block out java.util.Date. It's still accessible through reflection if any other class references it, or you can get an instance of it. You could block out the transitive closure of uses of Date, including those that in some way return a Date. However, to complete the scheme with your minimal date you'd have to load a java.util.Date in your class loader, which you can't along with all other java.* classes.
So, err, replace the java.util.Date class in rt.jar (possibly using a Java Agent), and substitute in any class you don't want to restrict new Date() with new Date(System.currentTimeMillis()).
(Btw, +1 to anything that reduces the dependency on System.currentTimeMillis() and other magic methods.)
To restrict access to certain packages, you have actually to change not the .policy file, but the security.properties. There is an entry package.access=... which lists the packages for which RuntimePermissions are needed. So, you can't restrict specifically the access to a single class, only to a whole package (including subpackages, if needed), i.e. java.util.
(You can alternatively access this by the Security.?etProperty methods.)
If you did this, you later can add the right RuntimePermission to the Policy to let the "good" code use it.
I think quite a good part of the JRE would cease working if you restrict access to java.util, so better try another class for testing.
The way the sandbox mostly works is that there are calls from classes that do security-sensitive stuff to the current SecurityManager to check whether or not such a call should succeed. Since the Date class isn't perceived to be security-sensitive, no such calls exist in it's code and that's why - as explained by Tom and Paulo - it is very difficult to restrict it.
For example, in contrast: File operations are perceived to be security sensitive and that's why the File class has calls to the SecurityManager. As an example the delete method:
public boolean delete() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkDelete(path);
}
return fs.delete(this);
}
And thanks to the SecurityManager check in the File class you can restrict File delete operations in the .policy file with more ease.
Related
So I have a bit of code, that creates an instance of a class.
Class<?> c = Class.forName("MyClass");
Constructor<?> cons = c.getConstructor();
cons.setAccessible(true);
Object instance = cons.newInstance();
Now I want to set some restrictions to that instance. When I call:
instance.doSomething();
I want to set restrictions for that bit of code (of the instance). So the methods called from that isntance can not do something fishy (System calls, File operations...).
I have tried to set a security manager, but that restricts all of the code (I still want to read/write files for the rest of my code).
Is it possible to restrict only certain objects?
TL;DR: Code
The question is essentially "How do I invoke a method on a particular instance, with privileges lower than normal?". There are three requirements here:
Code is to be authorized on a per-instance basis. An instance is privileged by default.
An instance may be selectively blacklisted, i.e., it may be accorded lower privileges than it normally would have been, for the duration of a method invocation that it receives.
Blacklisting must propagate to code executed on the receiver's behalf, specifically any objects of the same type that it interacts with, itself included; otherwise, if, say, the receiver were in turn to call
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
this.doSomethingElse();
return null;
});
doSomethingElse() would escape the sandbox.
All three are problematic:
The first one is not really1 achievable, because it presupposes that the runtime maintain—and expose—information about the instances (rather than merely the classes) on threads' execution stacks, which it does not2.
The second and third are only achievable as long as any blacklisted code does not assert its own (default, class-based) privileges via AccessController.doPrivileged(...), which, by design, it may at any time choose to.
Is there an alternative?
Well, how far are you willing to go? Modify AccessController / AccessControlContext internals? Or worse yet, internals of the VM? Or perhaps provide your own SecurityManager that reimplements the aforementioned components' functionality from scratch, in a way that satisfies your requirements? If the answer to all is "no", then I fear that your options are limited.
As an aside, you should ideally be able to make a binary choice when asked "Can or cannot this particular code, i.e. class, be entrusted with the particular privileges?", for this would tremendously simplify3 things. Unfortunately you cannot; and, to make matters worse, neither can you, presumably, modify the implementation of the class such that all of its instances can either be considered—with regards to a specific set of privileges—trustworthy or not, nor do you wish to simply mark the class, and therefore all of its instances, as untrusted (which I do believe you should!) and live with it.
Moving on to the proposed workaround. To overcome the shortcomings listed earlier, the original question will be rephrased as follows: "How do I invoke a method with elevated privileges accorded to the method receiver's ProtectionDomain?" I am going to answer this derivative question instead, suggesting, in contrast to the original one, that:
Code is to be authorized by the ProtectionDomain of its class, as is normally the case. Code is sandboxed by default.
Code may be selectively whitelisted, for the duration of a method invocation under a particular thread.
Whitelisting must propagate4 to code of the same class called by the receiver.
The revised requirements will be satisfied by means of a custom ClassLoader and DomainCombiner. The purpose of the first is to assign a distinct ProtectionDomain per class5; the other's is to temporarily replace the domains of individual classes within the current AccessControlContext for "on-demand whitelisting" purposes. The SecurityManager is additionally extended to prevent thread creation by unprivileged code4.
Note: I relocated the code to this gist to keep the post's length below the limit.
Standard disclaimer: Proof-of-concept code—take with several tablespoons of salt!
Running the example
Compile and deploy the code as suggested by the example policy configuration file, i.e., there should be two6 unrelated classpath entries (e.g. sibling directories at the filesystem level)—one for classes of the com.example.trusted package, and another for com.example.untrusted.Nasty.
Ensure also that you have replaced the policy configuration with the example one, and have modified the paths therein as appropriate.
Lastly run (after having appropriately modified the classpath entries, of course):
java -cp /path/to/classpath-entry-for-trusted-code:/path/to/classpath-entry-for-untrusted-code -Djava.system.class.loader=com.example.trusted.DiscriminatingClasspathClassLoader com.example.trusted.Main
The first call to the untrusted method should hopefully succeed, and the second fail.
1 It would perhaps be possible for instances of a specially crafted class (having, e.g., a domain of their own, assigned by some trusted component) to exercise their own privileges themselves (which does not hold true in this case, since you have no control over the implementation of instance's class, it appears). Nevertheless, this would still not satisfy the second and third requirement.
2 Recall that, under the default SecurityManager, a Permission is granted when all ProtectionDomains—to which normally classes, rather than instances, are mapped—of the thread's AccessControlContext imply that permission.
3 You would then simply have to grant permissions at the policy level, if you deemed the class trustworthy, or otherwise grant nothing at all, rather than have to worry about permissions per instance per security context and whatnot.
4 This is a hard decision: If whitelisting did not affect subsequent callees of the same type, the instance would not be able to call any privilege-requiring methods on itself. Now that it does, on the other hand, any other instance of the same type, that the original whitelisted method receiver interacts with, become privileged too! Thus you must ensure that the receiver does not call any "untrusted" instances of its own kind. It is for the same reason a bad idea to allow the receiver to spawn any threads.
5 As opposed to the strategy employed by the default application ClassLoader, which is to group all classes that reside under the same classpath entry within a single ProtectionDomain.
6 The reason for the inconvenience is that the ProtectionDomain, which our custom application ClassLoader's class gets mapped to by its parent, has a CodeSource implying all CodeSources referring to files under the loader's classpath entry. So far so good. Now, when asked to load a class, our loader attempts to discern between system/extension classes (loading of which it delegates to its parent) and application classes, by testing whether the .class file is located below JAVA_HOME. Naturally, to be allowed to do so, it requires read access to the filesystem subtree beneath JAVA_HOME. Unfortunately, granting the corresponding privilege to our loader's (notoriously broad) domain, implicitly grants the privilege to the domains of all other classes residing beneath the loader's classpath entry, including untrusted ones, as well. And that should hopefully explain why classpath entry-level isolation between trusted and untrusted code is necessary. There are of course workarounds, as always; e.g. mandating that trusted code be additionally signed in order to accrue any privileges; or perhaps using a more flexible URL scheme for code source identification, and/or altering code source implication semantics.
Further reading:
Default Policy Implementation and Policy File Syntax
API for Privileged Blocks
Secure Coding Guidelines for Java SE - §9 - Access Control
Troubleshooting Security
Historical note: Originally this answer proposed a nearly identical solution that abusedrelied on JAAS's SubjectDomainCombiner, rather than a custom one, for dynamic privilege modification. A "special" Principal would be attached to specific domains, which would then accrue additional Permissions upon evaluation by the Policy, based on their composite CodeSource-Principal identity.
I always thought that SecurityManagers included a check method which was called when Method/Field.setAccessible() was attempted that included a Permission that included the name of the method/field enclosing class and member name etc. Apparently it does not which is a shock.
I had an idea that it would be possible to solve this problem by using a ClassLoader that rewrote attempts such as
Method.setAccessible()
to
MethodHelper.setAccessible( Method );
The MethodHelper method could set a thread local which my security manager look at and clear to get the actual Method.
This of course has some potential flaws as it requires class file rewriting which of course can only happen for non system classes.
The same approach could be taken for retrieving methods, fields, etc which today do make the member available to the SecurityManager in any form.
Are there any FOSS libraries that package the above functionality ?
I have been using quite a lot of
System.getProperty("property")
in order to obtain environmental information. However, it seems to me that Sun prefers the following :
(String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("property"));
The strange thing is that this code involves a cast and as a result should be slightly slower than the
System.getProperty
implementation, that only uses a security manager and then instantly fetches the property from the instance variable props. My question is why did Sun chose to use the second method to obtain most environmental variables in their code internally, while
System.getProperty
seems like the faster way to go?
Both methods have a different meaning, and thus the right one has to be used depending on what the current code needs to do.
The code System.getProperty("property") says "Give me the value of the property, if the current security context allows me to read it."
The code that uses doPrivileged says "Give me the value of the property, if the current class (where this line of code is in) is allowed to read it."
The difference comes into play, when the protection domain of the current class is different from the currently active security context.
For example, consider a framework which executes the code of a plugin, which is untrusted. So the framework uses a SecurityManager to restrict the actions of the untrusted plugin code. But of course the plugin may call some methods of the framework, and suppose that one of these methods needs to read a property. Now as the method is called from untrusted restricted code, it is itself restricted and thus reading the property would fail. But of course the framework trusts itself and wants itself to be able to read that property, even in the case that somewhere in the call stack is untrusted code. That's when you need to use doPrivileged. It basically says "no matter what is up there in the call stack, I am a piece of framework code, and I am allowed to do whatever the framework code is allowed to do". So reading the property using the second method succeeds.
Of course one needs to be careful when using doPrivileged in order to not let the (untrusted) calling code do to much. If, for example, the framework code offers the following method to the plugin:
public String getProp(String key) {
return (String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction(key));
}
this would completely invalidate the policy that the untrusted code is not allowed to read system properties, because it can just use your method.
So use this method only when you know it is safe to do it, and only when you need it (which is, when you want your code to be able to do more than some other code should be able to do directly). Inside a normal application (which usually runs with no SecurityManager or the same security context for all code), there is no difference and the first method should be used.
I would recommend to stick with System.getProperty() since sun.security.action.GetPropertyAction seems to be proprietary to SUN and will not work on all Java VM implementations. Even the compiler warns you about it as:
warning: sun.security.action.GetPropertyAction is Sun proprietary API and may be removed in a future release
To understand what it actually means see this answer.
The reason to use a class like sun.security.action.GetPropertyAction is to avoid loading several, basically identical classes.
If you wrote:
(String) java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<java.lang.String>() {
String run() {
System.getProperty("property");
}
}
);
Each time you wanted to get a system property, you would load a new class for each getProperty call. Each class takes system resources and lives as long as the containing ClassLoader (forever for the bootclassloader).
Check out the javap output for more details:
javap -c -v -p sun.security.action.GetPropertyAction
Is there a feasible way to get my own code run whenever any class is loaded in Java, without forcing the user explicitly and manually loading all classes with a custom classloader?
Without going too much into the details, whenever a class implementing a certain interface read its annotation that links it with another class, and give the pair to a third class.
Edit: Heck, I'll go to details: I'm doing an event handling library. What I'm doing is having the client code do their own Listener / Event pairs, which need to be registered with my library as a pair. (hm, that wasn't that long after all).
Further Edit: Currently the client code needs to register the pair of classes/interfaces manually, which works pretty well. My intent is to automate this away, and I thought that linking the two classes with annotations would help. Next, I want to get rid of the client code needing to keeping the list of registrations up to date always.
PS: The static block won't do, since my interface is bundled into a library, and the client code will create further interfaces. Thus, abstract classes won't do either, since it must be an interface.
If you want to base the behavior on an interface, you could use a static initializer in that interface.
public interface Foo{
static{
// do initializing here
}
}
I'm not saying it's good practice, but it will definitely initialize the first time one of the implementing classes is loaded.
Update: static blocks in interfaces are illegal. Use abstract classes instead!
Reference:
Initializers (Sun Java Tutorial)
But if I understand you right, you want the initialization to happen once per implementing class. That will be tricky. You definitely can't do that with an interface based solution. You could do it with an abstract base class that has a dynamic initializer (or constructor), that checks whether the requested mapping already exists and adds it if it doesn't, but doing such things in constructors is quite a hack.
I'd say you cleanest options are either to generate Code at build time (through annotation processing with apt or through bytecode analysis with a tool like asm) or to use an agent at class load time to dynamically create the mapping.
Ah, more input. Very good. So clients use your library and provide mappings based on annotations. Then I'd say your library should provide an initializer method, where client code can register classes. Something like this:
YourLibrary.getInstance().registerMappedClasses(
CustomClass1.class,
CustomClass2.class,
CustomClass3.class,
CustomClass4.class
)
Or, even better, a package scanning mechanism (example code to implement this can be found at this question):
YourLibrary.getInstance().registerMappedClassesFromPackages(
"com.mycompany.myclientcode.abc",
"com.mycompany.myclientcode.def"
)
Anyway, there is basically no way to avoid having your clients do that kind of work, because you can't control their build process nor their classloader for them (but you could of course provide guides for classloader or build configuration).
If you want some piece of code to be run on any class loading, you should:
overwrite the ClassLoader, adding your own custom code at the loadClass methods (don't forget forwarding to the parent ClassLoader after or before your custom code).
Define this custom ClassLoader as the default for your system (here you got how to do it: How to set my custom class loader to be the default?).
Run and check it.
Depending on what kind of environment you are, there are chances that not all the classes be loaded trouugh your custom ClassLoader (some utility packages use their own CL, some Java EE containers handle some spacific areas with specific classLoaders, etc.), but it's a kind of aproximation to what you are asking.
This question already has answers here:
How can I get a list of all the implementations of an interface programmatically in Java?
(11 answers)
Closed 9 years ago.
Some time ago, I came across a piece of code, that used some piece of standard Java functionality to locate the classes that implemented a given interface. I know the functions were hidden in some non-logical place, but they could be used for other classes as the package name implied. Back then I did not need it, so I forgot about it, but now I do, and I can't seem to find the functions again. Where can these functions be found?
Edit: I'm not looking for any IDE functions or anything, but rather something that can be executed within the Java application.
Awhile ago, I put together a package for doing what you want, and more. (I needed it for a utility I was writing). It uses the ASM library. You can use reflection, but ASM turned out to perform better.
I put my package in an open source library I have on my web site. The library is here: http://software.clapper.org/javautil/. You want to start with the with ClassFinder class.
The utility I wrote it for is an RSS reader that I still use every day, so the code does tend to get exercised. I use ClassFinder to support a plug-in API in the RSS reader; on startup, it looks in a couple directory trees for jars and class files containing classes that implement a certain interface. It's a lot faster than you might expect.
The library is BSD-licensed, so you can safely bundle it with your code. Source is available.
If that's useful to you, help yourself.
Update: If you're using Scala, you might find this library to be more Scala-friendly.
Spring can do this for you...
BeanDefinitionRegistry bdr = new SimpleBeanDefinitionRegistry();
ClassPathBeanDefinitionScanner s = new ClassPathBeanDefinitionScanner(bdr);
TypeFilter tf = new AssignableTypeFilter(CLASS_YOU_WANT.class);
s.addIncludeFilter(tf);
s.scan("package.you.want1", "package.you.want2");
String[] beans = bdr.getBeanDefinitionNames();
N.B. The TypeFilter is important if you want the correct results!
You can also use exclusion filters here instead.
The Scanner can be found in the spring-context jar, the registry in spring-beans, the type filter is in spring-core.
I really like the reflections library for doing this.
It provides a lot of different types of scanners (getTypesAnnotatedWith, getSubTypesOf, etc), and it is dead simple to write or extend your own.
The code you are talking about sounds like ServiceLoader, which was introduced in Java 6 to support a feature that has been defined since Java 1.3 or earlier. For performance reasons, this is the recommended approach to find interface implementations at runtime; if you need support for this in an older version of Java, I hope that you'll find my implementation helpful.
There are a couple of implementations of this in earlier versions of Java, but in the Sun packages, not in the core API (I think there are some classes internal to ImageIO that do this). As the code is simple, I'd recommend providing your own implementation rather than relying on non-standard Sun code which is subject to change.
Package Level Annotations
I know this question has already been answered a long time ago but another solution to this problem is to use Package Level Annotations.
While its pretty hard to go find all the classes in the JVM its actually pretty easy to browse the package hierarchy.
Package[] ps = Package.getPackages();
for (Package p : ps) {
MyAno a = p.getAnnotation(MyAno.class)
// Recursively descend
}
Then just make your annotation have an argument of an array of Class.
Then in your package-info.java for a particular package put the MyAno.
I'll add more details (code) if people are interested but most probably get the idea.
MetaInf Service Loader
To add to #erickson answer you can also use the service loader approach. Kohsuke has an awesome way of generating the the required META-INF stuff you need for the service loader approach:
http://weblogs.java.net/blog/kohsuke/archive/2009/03/my_project_of_t.html
You could also use the Extensible Component Scanner (extcos: http://sf.net/projects/extcos) and search all classes implementing an interface like so:
Set<Class<? extends MyInterface>> classes = new HashSet<Class<? extends MyInterface>>();
ComponentScanner scanner = new ComponentScanner();
scanner.getClasses(new ComponentQuery() {
#Override
protected void query() {
select().
from("my.package1", "my.package2").
andStore(thoseImplementing(MyInterface.class).into(classes)).
returning(none());
}
});
This works for classes on the file system, within jars and even for those on the JBoss virtual file system. It's further designed to work within standalone applications as well as within any web or application container.
In full generality, this functionality is impossible. The Java ClassLoader mechanism guarantees only the ability to ask for a class with a specific name (including package), and the ClassLoader can supply a class, or it can state that it does not know that class.
Classes can be (and frequently are) loaded from remote servers, and they can even be constructed on the fly; it is not difficult at all to write a ClassLoader that returns a valid class that implements a given interface for any name you ask from it; a List of the classes that implement that interface would then be infinite in length.
In practice, the most common case is an URLClassLoader that looks for classes in a list of filesystem directories and JAR files. So what you need is to get the URLClassLoader, then iterate through those directories and archives, and for each class file you find in them, request the corresponding Class object and look through the return of its getInterfaces() method.
Obviously, Class.isAssignableFrom() tells you whether an individual class implements the given interface. So then the problem is getting the list of classes to test.
As far as I'm aware, there's no direct way from Java to ask the class loader for "the list of classes that you could potentially load". So you'll have to do this yourself by iterating through the visible jars, calling Class.forName() to load the class, then testing it.
However, it's a little easier if you just want to know classes implementing the given interface from those that have actually been loaded:
via the Java Instrumentation framework, you can call Instrumentation.getAllLoadedClasses()
via reflection, you can query the ClassLoader.classes field of a given ClassLoader.
If you use the instrumentation technique, then (as explained in the link) what happens is that your "agent" class is called essentially when the JVM starts up, and passed an Instrumentation object. At that point, you probably want to "save it for later" in a static field, and then have your main application code call it later on to get the list of loaded classes.
If you were asking from the perspective of working this out with a running program then you need to look to the java.lang.* package. If you get a Class object, you can use the isAssignableFrom method to check if it is an interface of another Class.
There isn't a simple built in way of searching for these, tools like Eclipse build an index of this information.
If you don't have a specific list of Class objects to test you can look to the ClassLoader object, use the getPackages() method and build your own package hierarchy iterator.
Just a warning though that these methods and classes can be quite slow.