Authorization layer API and low level access checks.

Peter Firmstone peter.firmstone at zeus.net.au
Thu Jun 24 01:50:25 UTC 2021


Clarification inline below.

On 24/06/2021 11:03 am, Peter Firmstone wrote:
> Hi Alan,
>
> It is important to understand the reason for the inherited 
> AccessControlContext, in order to consider alternatives.
>
> The motivation for inherited context, was simply to avoid privilege 
> escalation, prior to Executors.
>
> Whenever a permission check is made, the DomainCombiner, combines the 
> inherited context, with the thread's current context, in case there 
> are any less privileged domains in the inherited context.
>
> But there is an alternative, higher performance option, that avoids 
> privilege escalation for executors as well.
>
> A ProtectionDomain with a null CodeSource has AllPermission, while a 
> ProtectionDomain that contains a CodeSource with a null URL has only 
> the Permission's given to it when created, or to blanket grant 
> statements in policy files.
>
> Rather than inherit context from the calling thread, all threads upon 
> creation could be initialized with one shared immutable unprivileged 
> AccessControlContext, containing a single element array, with a 
> ProtectionDomain, containing a CodeSource with a null URL.
>
> Code cannot assume that calling code is privileged, hence the 
> AccessController.doPrivileged method, so an unprivileged context could 
> replace system threads inherited context as well.   There will be some 
> minor impacts in older code where developers create a system thread 
> for cleanup tasks or other things, but nothing that couldn't be worked 
> around, until it can be addressed properly. This is an existential 
> moment for Java authorization, as a developer with extensive use of 
> Java authorization, I would most certainly welcome this change.
>
> This would be a simplification that enhances security.   This is far 
> more preferable than an inherited AccessControlContext as it 
> eliminates any risk that Executor tasks present, where domains in the 
> context that creates Callable or Runnable, may not be in the inherited 
> thread context.  JEP 411, presents an opportunity to address it.
>
> A use case:
>
> I would like to use virtual threads, in executors, to make blocking 
> secure network connections, so I don't consume too many system 
> threads.   When network failures occur, the number of threads created 
> increase significantly, as blocked threads waiting on network are no 
> longer available to the executor.
>
> All our executor tasks are wrapped, with AccessControlContext, using 
> Executors::callable(PrivilegedAction), we do this to capture the 
> Subject, and to grant SocketPermission (to Principles and CodeSource) 
> to make secure network calls from one node to another.  Across the 
> network, the user Subject's Principals are preserved, from the thread 
> in the client to the thread in the server during authentication.  
> DeserializationPermission is granted to the user Principal's and 
> CodeSource in the server, so that the code cannot perform 
> deserialization (not to be confused with Java serialization) without 
> an authenticated user.   The authenticated user represents the domain 
> from which data to be deserialized originates.
>
> Personally I would like to see AccessController and 
> AccessControlContext retained, and all threads modified to be 
> initialized with a single shared immutable unprivileged 
> AccessControlContext, rather than an inherited AccessControlContext in 
> system threads and virtual threads that do not support any permissions 
> at all.
All threads except bootstrap threads in the JVM, obviously they would 
need to be privileged.

-- 
Regards,
  
Peter Firmstone




More information about the security-dev mailing list