41

If I understand 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

Community
  • 1
  • 1
Gili
  • 86,244
  • 97
  • 390
  • 689

4 Answers4

25

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.

Community
  • 1
  • 1
Ash
  • 9,296
  • 2
  • 24
  • 32
  • 2
    @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 Feb 11 '10 at 18:14
  • @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 Feb 12 '10 at 10:25
15
  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
  • 24,433
  • 12
  • 63
  • 94
  • @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 Feb 11 '10 at 03:41
  • @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 Feb 11 '10 at 04:45
  • @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 Feb 11 '10 at 04:50
  • 4
    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 Feb 11 '10 at 09:04
  • 3
    @Suraj, I've revisited this issue and I think your first point is wrong. My understanding is as follows: `A` doesn't have access to files on disk, but `A` is allowed to construct a `Font` even though this accesses files on disk under the hood. Class `Font` wraps its file access inside a `doPrivileged()` block, essentially saying "trust me to invoke privileged code even if my caller does not have permission. I promise I won't let him do anything he shouldn't". Do you agree? – Gili Nov 13 '11 at 04:34
  • 1
    @Gilli I think you misunderstood it. In first point I say that "e final effective permissions is the intersection of all permissions in the domain stack". To overcome this you use AccessController.doPriveleged. And thats what the Font class does as you observed. – Suraj Chandran Nov 13 '11 at 11:02
  • @suraj But here Font should have the access to the files for the doPriveleged to work right? – chebus May 11 '16 at 11:18
10

Essentially, AccessController.doPriviledged() is the equivalent of a set-user-id file. It is saying "I hereby request that this method be done with my privileges, even if I was invoked by a method that does not have them."

Demi
  • 3,535
  • 5
  • 29
  • 45
4

Check out these links and scroll down to using the doPrivileged API.

Java 6: http://docs.oracle.com/javase/6/docs/technotes/guides/security/doprivileged.html

Java 7: http://docs.oracle.com/javase/7/docs/technotes/guides/security/doprivileged.html

When the AccessController checkPermission method is invoked by the most recent caller, the basic algorithm for deciding whether to allow or deny the requested access is as follows:

If the code for any caller in the call chain does not have the requested permission, AccessControlException is thrown, unless the following is true - a caller whose code is granted the said permission has been marked as "privileged" (see below) and all parties subsequently called by this caller (directly or indirectly) all have the said permission

Tim
  • 49
  • 1
  • 1
    The quote that caught my attention is: `Marking code as "privileged" enables a piece of trusted code to temporarily enable access to more resources than are available directly to the code that called it. This is necessary in some situations. For example, an application may not be allowed direct access to files that contain fonts, but the system utility to display a document must obtain those fonts, on behalf of the user. In order to do this, the system utility becomes privileged while obtaining the fonts.` – Gili Jan 19 '12 at 15:34