views:

170

answers:

6

So after a few hours of workaround the limitation of Reflection being currently disabled on the Google App Engine, I was wondering if someone could help me understand why object reflection can be a threat. Is it because I can inspect the private variables of a class or are there any other deeper reasons?

+2  A: 

Check out this question.

dbyrne
The article is about .net. Are .net and java comparable w.r.t. reflection and security?
ewernli
I don't think thats an answer.
Rook
+2  A: 

An application can use the Java reflection APIs to access and update fields, and execute methods that are forbidden by normal Java access / visibility rules. With a bit of ingenuity, this is sufficient to:

  • access information that is supposed to be hidden,
  • subvert the Java security sandbox so that you can interfere with other things running in the JVM, access files on the local machine, and so on.

Under certain circumstances, it might even allow the injection of malicious native code.

Stephen C
Interesting, could you provide more details? Perhaps a link.
Rook
+3  A: 

1 - Reflection (as a concept) is indeed orthogonal to safety/security.

There was a big emphasis in the design of java to make it a safe platform, with static typing, security manager, disciplined usage of class loader, and no way to screw pointers/memory. You can read the interview of James Gosling in Masterming of programming, which is interesting about that.

But the more reflective power you have the harder it is to ensure things are safe as they should. Reflection defeat notably static typing and can lead to run-time errors.

But more subtle things can happen as well. For instance class loaders -- which can be considered as reflective hook in the system -- were not designed properly in the early version of Java leading to potential type replacement. The article Dynamic class loading in the JVM, by Gilad Bracha, is insightful on such issues.

Reflection can not be turned off altogether; it's always possible to reflect on its own public fields/methods. Reflection on private structures with AccessibleObject.setAccessible can however be disabled, because it breaks encapsulation. With access to private fields, etc. inspection and modification of internal data is possible. It can lead to various malicious exploits, e.g.

  • strings are not immutable anymore and can be changed (see this question)
  • you can reveal sensible information of objects you don't own
  • ... other exploits ...

Finally there are other mechanism that put security in jeopardy, notably sun.misc.Unsafe which gives direct access to the memory -- pointers are back.

2 - Now, the question is whether reflection (in practice) leads to that many risks.

I've read the link pointed by @dbyrne but it's mostly about .net. Also I don't know exactly what is disabled for Google App. Is it the ReflectPermission only, or other permission of the security manager? One danger is clearly to get access to the file system and mess around.

The problem of access to private data and breaking encapsulation can be argued in practice. Writing secure code is indeed extremely hard, and even without changing the access modifier you can subclass classes in an inappropriate way -- unless they are final, or even better, sealed -- and pass them around. This is for instance what defensive copying try to protect against.

Type-safety is also anyway threatened by run-time error because of downcast, so this point can also be argued.

In a shared/hosted environment, the security is relative. At the language level, you can for instance not prevent a module form consuming 100% of CPU or consuming all memory up to a OutOfMemoryException. Such concerns need to be addressed by other means, typically at the OS level, with virtualization and quotas.

So my personal answer, would be: reflection is a security risk, but not that big in practice if compared to other potential attack vectors.

ewernli
+1 for providing an excellent link. I respectfully disagree with your attack scenario although I admit all we have is speculation.
Rook
@ewernli: Thanks for the detailed explanation. This question in fact stems from my other question: http://stackoverflow.com/questions/3002714/gson-on-google-app-engine-throws-a-security-exception . The answer provided says otherwise but I still don't understand why GSON does things the way it is doing. I ended up writing my own little toJSON method but this approach is simply not acceptable for large objects. That gets me to my final question: If not reflection, is there any other way I can do what I was trying to do? Any thoughts?
Legend
@Legend Apparently GSON try to use `AccessibleObject.setAccessible` when it's disallowed. I'm not familiar with GSON, and why it needs to change the access modifier. I guess you should look at GSON's code if you want to understand that. Maybe you could make your own version of GSON that uses reflection but doesn't use `AccessibleObject.setAccessible` and make sure that you pass objects for serialization where all fields/methods are public.
ewernli
A: 

A theory of mine is that Google is trying to hide something. By disabling Reflection Google could hide Variable names, function calls and an even a full API. If Google is hiding something like an API, then they certainty aren't going to tell you about it.

I know for a fact that Reflection plays a very important role in security testing. For instance you can automatically generate Fuzz tests using reflection. AxMan uses TypeLib to identify all of the classes and their method calls that make up a COM object. Using this information AxMan will then instantiate each class and call every method with permutations of long strings and large numbers. Similar testing is conducted by SOAP Fuzzers using the WSDL file for reflection.

Rook
+1  A: 

First off, if you've not installed a SecurityManager then you're not secure anyway.

Secondly, reflection doesn't open up significant holes unless the setAccessible() is enabled, and that itself is subject to a security check (governed by the setAccessChecks reflection permission). Without that, while you might be able to know that the private field or method exists (though that itself requires the accessDeclaredMembers runtime permission) you can't do anything much with that knowledge. Your best bet to attack might be to work with serialized objects, but that's a whole 'nother ball of wax.

Note also that writing a secure security manager and class loader is non-trivial. Best to leave those to others if you're not aspiring to mega-guru-dom (or, more likely, embarrassing levels of failure).

Donal Fellows
A: 

GAE is a shared hosting environment, and hosts WAR files from multiple users. It is highly likely that multiple WAR files are hosted in the same JVM, because spawning a process per WAR is just ridiculous. So, the only way to sandbox each war file is via a custom classloader for each WAR file.

Now, assume that reflection was allowed. You could then walk the classloader hierarchy and enumerate classes/methods from WAR files belonging to different users. Obviously, that is a big concern.

sri