tags:

views:

291

answers:

2

If I understand http://stackoverflow.com/questions/852453/accesscontroller-doprivileged correctly, it is saying that untrusted code should be able to invoke methods requiring permissions (such as System.getProperty()) through an intermediate method that does have permissions.

That brings up the question: when should AccessController.doPrivileged() be used? When should untrusted code be allowed to invoke privileged code through intermediate methods? When should it fail?

Following your reasoning, please explain why ClassLoader creation should always be allowed: http://findbugs.sourceforge.net/bugDescriptions.html#DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED

+2  A: 
  1. ..through an intermediate method that does have permissions . No, the final effective permissions is the intersection of all permissions in the domain stack. So suppose an operation requires a permission B to execute, and say some intermediate LIB has two permissions B and A. Now when some untrusted code with only permission A calls through LIB, the effective permission set is (A intersect (A+B)) = A. Hence the untrusted code cannot exploit intermediate LIB to gain extra permissions.

  2. When should doPriveleged be used?-> There are lot of operations in Java that require the caller domain to have certain permissions for successful execution of those operations. System.getProperty is one of those operations. All file related operations also need special permissions. When you use AccessController.doPrivileged to invoke those operations, the operation is executed with all the rights(permissions) of your protection domain. Hence if your code has enough rights only then it could execute those operations.

Suraj Chandran
@Suraj, "When you use AccessController.doPrivileged to invoke those operations, the operation is executed with all the rights(permissions) of your protection domain". Can you please provide an example of what permissions would be with and without the use of doPrivileged()?
Gili
@Gilli..this will asnwer your question.."Technically, whenever a resource access is attempted, all code traversed by the execution thread up to that point must have permission for that resource access, unless some code on the thread has been marked as "privileged" by a doPriveleged block"
Suraj Chandran
@Gilli...Suppose a thread traverses through three code bases A,B and C before executing a secured operation. A and C don't have permission for that operation but B does. If you dont use doPriveleged in B and end up calling the secured operation, you will get a SecurityException as C does not have enough permissions. But if you use a doPriveleged block in B before callling in to C, then even C will also execute with those permissions, hence you can now ecexute the secure operation.
Suraj Chandran
@Suraj, I agree that if A calls B a privileged block is required to adopt only B's permissions. But if B then calls through to C (even from within a privileged block), won't it fail if C's context doesn't have the required permissions? Doesn't it still start calling up from the permission "stack" again? (I haven't done anything in this area for a while to test it - just working off the AccessController docs).
Ash
+1  A: 

Agree with Suraj's answer, but thought I'd add a specific example where I've required the use of a privileged block.

Imagine you've built an application that provides a number of services to pluggable modules. So your app and its services are trusted code. The pluggable modules, however, are not necessarily trusted and are loaded in their own class loaders (and have their own protection domains).

When a pluggable module invokes a service, you are implementing custom security checks ("does pluggable module X have permission to use this service"). But the service itself might require some core Java permission (read a system property, write to a file, etc). The code that requires these permissions is wrapped in a doPrivileged() so that the insufficient permissions from the untrusted pluggable modules are effectively ignored - only the privileges of your trusted services module apply.

Ash
@Ash, given A which has permission to invoke X but B does not, and A invokes B which invokes X. Does doPrivileged() mean "B doesn't have permission to invoke X, but I do and I vouch for him. So A is now allowed to invoke X"?
Gili
@Gili, my understanding is that the doPrivileged() block assumes the permissions of the current protection domain, excluding anything further back in the stack. It won't necessarily pass permissions forward to future calls that themselves have lesser permissions (I'm kind of working from memory and interpreting the documentation - see my comment in Suraj's answer).
Ash