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