Class NashornSandboxImpl

  • All Implemented Interfaces:
    NashornSandbox

    public class NashornSandboxImpl
    extends java.lang.Object
    implements NashornSandbox
    Nashorn sandbox implementation.

    Created on 2015-08-07

    Version:
    $Id$
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void allow​(java.lang.Class<?> clazz)
      Add a new class to the list of allowed classes.
      void allowExitFunctions​(boolean v)
      Allow Nashorn quit and exit functions.
      void allowGlobalsObjects​(boolean v)
      Allow Nashorn globals object $ARG, $ENV, $EXEC, $OPTIONS, $OUT, $ERR and $EXIT.
      void allowLoadFunctions​(boolean v)
      Allow Nashorn load and loadWithNewGlobal functions.
      void allowNoBraces​(boolean v)
      Force, to check if all blocks are enclosed with curly braces "{}".
      void allowPrintFunctions​(boolean v)
      Allow Nashorn print and echo functions.
      void allowReadFunctions​(boolean v)
      Allow Nashorn readLine and readFully functions.
      private void assertScriptEngine()  
      private void checkExecutorPresence()  
      javax.script.CompiledScript compile​(java.lang.String js)
      Compile the JavaScript string
      javax.script.Bindings createBindings()
      Create new bindings used to replace the state of the current script engine
      javax.script.ScriptEngine createNashornScriptEngineFactory​(java.lang.String... params)  
      private SandboxClassFilter createSandboxClassFilter()  
      void disallow​(java.lang.Class<?> clazz)
      Remove a class from the list of allowed classes.
      void disallowAllClasses()
      Remove all classes from the list of allowed classes.
      private boolean engineBindingUnchanged()  
      java.lang.Object eval​(java.lang.String js)
      Evaluates the JavaScript string.
      java.lang.Object eval​(java.lang.String js, javax.script.Bindings bindings)
      Evaluates the JavaScript string.
      java.lang.Object eval​(java.lang.String js, javax.script.ScriptContext scriptContext)
      Evaluates the JavaScript string for a given script context
      java.lang.Object eval​(java.lang.String js, javax.script.ScriptContext scriptContext, javax.script.Bindings bindings)
      Evaluates the JavaScript string for a given script context
      java.lang.Object eval​(javax.script.CompiledScript compiledScript)
      Run a pre-compiled JavaScript
      java.lang.Object eval​(javax.script.CompiledScript compiledScript, javax.script.Bindings bindings)  
      java.lang.Object eval​(javax.script.CompiledScript compiledScript, javax.script.ScriptContext scriptContext)  
      java.lang.Object eval​(javax.script.CompiledScript compiledScript, javax.script.ScriptContext scriptContext, javax.script.Bindings bindings)  
      protected java.lang.Object executeSandboxedOperation​(ScriptEngineOperation op)  
      java.lang.Object get​(java.lang.String variableName)
      Obtains the value of the specified JavaScript variable.
      private JsEvaluator getEvaluator​(ScriptEngineOperation op)  
      java.util.concurrent.ExecutorService getExecutor()
      Gets the current executor service.
      private javax.script.Invocable getLazySandboxedInvocable()  
      javax.script.Invocable getSandboxedInvocable()
      Returns an Invocable instance, so that method invocations are also sandboxed.
      protected JsSanitizer getSanitizer()  
      void inject​(java.lang.String variableName, java.lang.Object object)
      Will add a global variable available to all scripts executed with this sandbox.
      boolean isAllowed​(java.lang.Class<?> clazz)
      Check if a class is in the list of allowed classes.
      private void produceSecureBindings()  
      protected void resetEngineBindings()  
      protected void sanitizeBindings​(javax.script.Bindings bindings)  
      protected javax.script.Bindings secureBindings​(javax.script.Bindings bindings)  
      void setExecutor​(java.util.concurrent.ExecutorService executor)
      Specifies the executor service which is used to run scripts when a CPU time limit is specified.
      void setMaxCPUTime​(long limit)
      Sets the maximum CPU time in milliseconds allowed for script execution.
      void setMaxMemory​(long limit)
      Sets the maximum memory in Bytes which JS executor thread can allocate.
      void setMaxPreparedStatements​(int max)
      The size of prepared statements LRU cache.
      void setScriptCache​(SecuredJsCache cache)
      Overwrites the cache for pre-processed javascript.
      void setWriter​(java.io.Writer writer)
      Sets the writer, when want to have output from writer function called in JS script
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • LOG

        static final org.slf4j.Logger LOG
      • scriptEngine

        protected final javax.script.ScriptEngine scriptEngine
      • maxCPUTime

        protected long maxCPUTime
        Maximum CPU time in milliseconds.
      • maxMemory

        protected long maxMemory
        Maximum memory of executor thread used.
      • executor

        protected java.util.concurrent.ExecutorService executor
      • allowPrintFunctions

        protected boolean allowPrintFunctions
      • allowReadFunctions

        protected boolean allowReadFunctions
      • allowLoadFunctions

        protected boolean allowLoadFunctions
      • allowExitFunctions

        protected boolean allowExitFunctions
      • allowGlobalsObjects

        protected boolean allowGlobalsObjects
      • allowNoBraces

        protected boolean allowNoBraces
      • engineAsserted

        protected java.util.concurrent.atomic.AtomicBoolean engineAsserted
      • lazyInvocable

        protected javax.script.Invocable lazyInvocable
      • maxPreparedStatements

        protected int maxPreparedStatements
        The size of the LRU cache of prepared statements.
      • cached

        protected javax.script.Bindings cached
    • Constructor Detail

      • NashornSandboxImpl

        public NashornSandboxImpl()
      • NashornSandboxImpl

        public NashornSandboxImpl​(java.lang.String... params)
      • NashornSandboxImpl

        public NashornSandboxImpl​(javax.script.ScriptEngine engine,
                                  java.lang.String... params)
    • Method Detail

      • createNashornScriptEngineFactory

        public javax.script.ScriptEngine createNashornScriptEngineFactory​(java.lang.String... params)
      • assertScriptEngine

        private void assertScriptEngine()
      • engineBindingUnchanged

        private boolean engineBindingUnchanged()
      • produceSecureBindings

        private void produceSecureBindings()
      • resetEngineBindings

        protected void resetEngineBindings()
      • sanitizeBindings

        protected void sanitizeBindings​(javax.script.Bindings bindings)
      • eval

        public java.lang.Object eval​(java.lang.String js,
                                     javax.script.Bindings bindings)
                              throws ScriptCPUAbuseException,
                                     javax.script.ScriptException
        Description copied from interface: NashornSandbox
        Evaluates the JavaScript string.
        Specified by:
        eval in interface NashornSandbox
        Parameters:
        js - the JavaScript script to be evaluated
        bindings - the Bindings to use for evaluation
        Throws:
        ScriptCPUAbuseException - when execution time exceeded (when greater than 0 is set
        javax.script.ScriptException - when script syntax error occurs
        See Also:
        NashornSandbox.setMaxCPUTime(long)
      • eval

        public java.lang.Object eval​(java.lang.String js,
                                     javax.script.ScriptContext scriptContext)
                              throws ScriptCPUAbuseException,
                                     javax.script.ScriptException
        Description copied from interface: NashornSandbox
        Evaluates the JavaScript string for a given script context
        Specified by:
        eval in interface NashornSandbox
        Parameters:
        js - the JavaScript script to be evaluated
        scriptContext - the ScriptContext exposing sets of attributes in different scopes.
        Throws:
        ScriptCPUAbuseException - when execution time exceeded (when greater than 0 is set
        javax.script.ScriptException - when script syntax error occurs
        See Also:
        NashornSandbox.setMaxCPUTime(long)
      • eval

        public java.lang.Object eval​(java.lang.String js,
                                     javax.script.ScriptContext scriptContext,
                                     javax.script.Bindings bindings)
                              throws ScriptCPUAbuseException,
                                     javax.script.ScriptException
        Description copied from interface: NashornSandbox
        Evaluates the JavaScript string for a given script context
        Specified by:
        eval in interface NashornSandbox
        Parameters:
        js - the JavaScript script to be evaluated
        scriptContext - the ScriptContext exposing sets of attributes in different scopes.
        bindings - the Bindings to use for evaluation
        Throws:
        ScriptCPUAbuseException - when execution time exceeded (when greater than 0 is set
        javax.script.ScriptException - when script syntax error occurs
        See Also:
        NashornSandbox.setMaxCPUTime(long)
      • secureBindings

        protected javax.script.Bindings secureBindings​(javax.script.Bindings bindings)
      • checkExecutorPresence

        private void checkExecutorPresence()
      • setMaxMemory

        public void setMaxMemory​(long limit)
        Description copied from interface: NashornSandbox

        Sets the maximum memory in Bytes which JS executor thread can allocate.

        Note, thread memory usage is only approximation.

        Note, ExecutorService should be also set when memory limit is set greater than 0. Nashorn takes some memory at start, be generous and give at least 1MB. If bindings are used, Nashorn allocates additional memory for the bindings which might be a multiple of the memory theoretically required by the data types used. For details, see issue 86.

        Current implementation of this limit works only on Sun/Oracle JVM.

        Specified by:
        setMaxMemory in interface NashornSandbox
        Parameters:
        limit - limit in bytes
        See Also:
        ThreadMXBean.getThreadAllocatedBytes(long)
      • allow

        public void allow​(java.lang.Class<?> clazz)
        Description copied from interface: NashornSandbox
        Add a new class to the list of allowed classes.
        Specified by:
        allow in interface NashornSandbox
      • disallow

        public void disallow​(java.lang.Class<?> clazz)
        Description copied from interface: NashornSandbox
        Remove a class from the list of allowed classes.
        Specified by:
        disallow in interface NashornSandbox
      • isAllowed

        public boolean isAllowed​(java.lang.Class<?> clazz)
        Description copied from interface: NashornSandbox
        Check if a class is in the list of allowed classes.
        Specified by:
        isAllowed in interface NashornSandbox
      • inject

        public void inject​(java.lang.String variableName,
                           java.lang.Object object)
        Description copied from interface: NashornSandbox
        Will add a global variable available to all scripts executed with this sandbox.
        Specified by:
        inject in interface NashornSandbox
        Parameters:
        variableName - the name of the variable
        object - the value, can be null
      • setExecutor

        public void setExecutor​(java.util.concurrent.ExecutorService executor)
        Description copied from interface: NashornSandbox
        Specifies the executor service which is used to run scripts when a CPU time limit is specified.
        Specified by:
        setExecutor in interface NashornSandbox
        Parameters:
        executor - the executor service
        See Also:
        NashornSandbox.setMaxCPUTime(long)
      • getExecutor

        public java.util.concurrent.ExecutorService getExecutor()
        Description copied from interface: NashornSandbox
        Gets the current executor service.
        Specified by:
        getExecutor in interface NashornSandbox
        Returns:
        current executor service
      • get

        public java.lang.Object get​(java.lang.String variableName)
        Description copied from interface: NashornSandbox
        Obtains the value of the specified JavaScript variable.
        Specified by:
        get in interface NashornSandbox
      • allowNoBraces

        public void allowNoBraces​(boolean v)
        Description copied from interface: NashornSandbox
        Force, to check if all blocks are enclosed with curly braces "{}".

        Warning This option is useful to identify potential abuse but is also prone to identify false positives. Please use with caution. Alternatively you can use setMaxCPUTime to prevent abusive script execution.

        Explanation: all loops (for, do-while, while, and if-else, and functions should use braces, because poison_pill() function will be inserted after each open brace "{", to ensure interruption checking. Otherwise simple code like:

             while(true) while(true) {
               // do nothing
             }
           
        or even:
             while(true)
           
        cause unbreakable loop, which force this sandbox to use Thread.stop() which make JVM unstable.

        Properly written code (even in bad intention) like:

             while(true) { while(true) {
               // do nothing
             }}
           
        will be changed into:
             while(true) {poison_pill(); 
               while(true) {poison_pill();
                 // do nothing
               }
             }
           
        which finish nicely when interrupted.

        For legacy code, this check can be turned off, but with no guarantee, the JS thread will gracefully finish when interrupted.

        Specified by:
        allowNoBraces in interface NashornSandbox
        Parameters:
        v - true when sandbox should check if all required braces are placed into JS code, false when no check should be performed
      • setWriter

        public void setWriter​(java.io.Writer writer)
        Description copied from interface: NashornSandbox
        Sets the writer, when want to have output from writer function called in JS script
        Specified by:
        setWriter in interface NashornSandbox
        Parameters:
        writer - the writer, eg. StringWriter
      • createBindings

        public javax.script.Bindings createBindings()
        Description copied from interface: NashornSandbox
        Create new bindings used to replace the state of the current script engine

        This can be typically used to override ECMAScript "global" properties

        Specified by:
        createBindings in interface NashornSandbox
        Returns:
      • getSandboxedInvocable

        public javax.script.Invocable getSandboxedInvocable()
        Description copied from interface: NashornSandbox
        Returns an Invocable instance, so that method invocations are also sandboxed.
        Specified by:
        getSandboxedInvocable in interface NashornSandbox
        Returns:
      • getLazySandboxedInvocable

        private javax.script.Invocable getLazySandboxedInvocable()
      • compile

        public javax.script.CompiledScript compile​(java.lang.String js)
                                            throws javax.script.ScriptException
        Description copied from interface: NashornSandbox
        Compile the JavaScript string
        Specified by:
        compile in interface NashornSandbox
        Parameters:
        js - the JavaScript script to be compiled
        Returns:
        a CompiledScript object
        Throws:
        javax.script.ScriptException
      • eval

        public java.lang.Object eval​(javax.script.CompiledScript compiledScript,
                                     javax.script.ScriptContext scriptContext,
                                     javax.script.Bindings bindings)
                              throws ScriptCPUAbuseException,
                                     javax.script.ScriptException
        Specified by:
        eval in interface NashornSandbox
        Throws:
        ScriptCPUAbuseException
        javax.script.ScriptException