You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 23 Current »

IDIEP-38
Author
Sponsor
Created 16.10.2019
Status

ACTIVE


Motivation

For now, a user-defined code that executes on a remote node can utilize all feature Java to get access to host resources.

For example, it can create/update/delete files; create sockets; read/update/delete system properties; use reflection API and so on.

That behavior leads to security lack.

To protect resources on a remote node, we should restrict the opportunities of user-defined code.

Description

To protect crucial system resources, we should use the Java Sandbox.

The Sandbox is composed of the next elements:

  • Permissions. A permission is a specific action that code is allowed to perform.
  • Code sources. Code sources are the location from which a class has been loaded along with information about who signed the class, if applicable.
  • Protection domains. A protection domain is an association of permissions with a particular code source. Every class definition can refer to only one ProtectionDomain.
  • AccessController. The AccessController class is used for access control operations and decisions.
  • AccessControlContext. An AccessControlContext is used to make system resource access decisions based on the context it encapsulates.

Java uses a stack-based access control mechanism.
The standard security check ensures that each frame (Protection Domain) in the call stack has the required permission.
That is, the current permissions in force are the intersection of the permissions of each frame in the current access control context.
If any frame does not have permission, no matter where it lies in the stack, then the current context does not have that permission.

We have the opportunity to dynamically update the Protection Domains associated with the current AccessControlContext using the DomainCombiner interface.
A DomainCombiner is passed as a parameter to the appropriate constructor for AccessControlContext.
The newly constructed context is then passed to the AccessController.doPrivileged(..., context) method to bind the provided context (and associated DomainCombiner) with the current execution Thread.
Subsequent calls to AccessController.getContext or AccessController.checkPermission cause the DomainCombiner.combine to get invoked.

That is the basis to implement the integration of the Java Sandbox with Apache Ignite.

The main unit of the Ignite Sandbox is the IgniteSandbox interface, accessed through IgniteSecurity.
Users for this interface are components that can run a user-defined code. To run a user-defined code with restrictions,
they have to pass it to the IgniteSandbox.execute method.

There are a few conditions to run user-defined code with restrictions:

  • installed GridSecurityProcessor;
  • GridSecurityProcessor#sandboxEnabled == true;
  • installed SecurityManager.

If these conditions in the place, an instance of the AccessControllerSandbox class that is the implementation of IgniteSandbox runs a user-defined code with restrictions as follow:

  1. Get sandbox permissions from a SecuritySubject of the current SecurityContext.
  2. Create AccessControlContext with IgniteDomainCombiner that constructed using permissions from step 1.
  3. Call AccessController.doPrivileged with passed a user-defined code and AccessControlContext from step 2.

IgniteDomainCombiner is responsible for updating the Protection Domains with permissions of the current SecuritySubject.


A user-defined code should have the opportunity of using the public API of Ignite on a remote node.
But he may don't have some permissions to execute this operation successfully. For example, to put a value into a cache,
it requires permissions for accessing to reflection API and reading system property IGNITE_ALLOW_ATOMIC_OPS_IN_TX.
In that case, we have to use AccessController.doPrirvelged without AccessControlContext call to exclude a user-defined code from checking of permissions.

We can achieve that behavior by using a proxy of interface Ignite that executes methods inside a privileged block. Builder methods of Ignite proxy create a proxy of public interfaces (IgniteCache, IgniteCompute, and so on) that run their methods inside a privileged block too.
Additionally, using of Ignite proxy allows restricting access of a user-defined code to internal Ignite classes.

Phase 1.

  1. Create implementations of the IgniteSandbox interface.
  2. Extend interface IgniteSecurity to use IgniteSandbox.
  3. Extend interface SecuritySubject to get sandbox permissions.
  4. Execution a user-defined code in the Ignite Sandbox for the following components:
    a. ComputeJob;
    b. EntryProcessor;
    c. IgniteBiPredicate;
    d. IgniteClosure;
    e. StreamReceiver.


Phase 1 covers using the Sandbox for features:

  • cache: EntryProcessor, ScanQuery, load cache;
  • compute: execute, broadcast, call, run, apply, executorService;
  • DataStreamer.

Phase 2.

  1. Restrict access a user-defined code to internal API of Ignite:
    a. Restrict internal package access;
    b. Encapsulation of IgniteKernal.
  2. Execution a user-defined code in the Ignite Sandbox for the following features:
    a. Continuous Queries;
    b. IgniteMassaging;
    c. ServiceGrid.

Risks and Assumptions

The existing implementations of interfaces Runnable, IgniteRunnable,
Callable.class, IgniteCallable, ComputeTask, ComputeJob, IgniteClosure, IgniteBiClosure, IgniteDataStreamer, IgnitePredicate,
IgniteBiPredicate cannot cast the instance of Ignite to IgniteEx or IgniteKernal if the Sandbox is enabled.

Discussion Links

http://apache-ignite-developers.2346864.n4.nabble.com/Review-needed-for-IGNITE-11410-Sandbox-for-user-defined-code-td43955.html

Reference Links

https://docs.oracle.com/javase/8/docs/technotes/guides/security/spec/security-spec.doc1.html#a18313

https://docs.oracle.com/javase/8/docs/api/java/security/AccessController.html

https://docs.oracle.com/javase/7/docs/api/java/security/AccessControlContext.html

https://docs.oracle.com/javase/7/docs/api/java/security/DomainCombiner.html

https://docs.oracle.com/javase/8/docs/technotes/guides/security/spec/security-spec.doc6.html#a19349

Tickets

key summary type created assignee reporter priority status resolution

JQL and issue key arguments for this macro require at least one Jira application link to be configured







  • No labels