Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8043717

JEP 202: Nashorn Class Filter



    • Feature
    • Open
    • JDK
    • nashorn dash dev at openjdk dot java dot net
    • S
    • S
    • Dev and SQE completed, no Perf needed.
    • 202



      Provide fine-grained control over access to Java classes from JavaScript code.


      • Provide a Java class-access filtering interface, ClassFilter, that can be implemented by Java applications that use Nashorn.

      • Nashorn will query a provided instance of the ClassFilter interface before accessing any Java class from a script in order to determine whether the access is allowed. This will occur whether or not a security manager is present.

      • A script should not be able to subvert restrictions by a class filter in any way, not even by using Java's reflection APIs.


      The API will not:

      • Filter the public methods or fields of any object that is exposed to scripts. For example, if a Nashorn-embedding application exposes a value that is a Java object, all public methods of object that will be invocable from scripts.

      • Filter individual methods or fields.

      • Make security managers redundant for scripts. Embedding applications should still turn on security management before evaluating scripts from untrusted sources. Class filtering alone will not provide a complete script "sandbox." Even if only untrusted scripts (with no additional Java classes) are executed, a security manager should still be utilized. Class filtering provides finer control beyond what a security manager provides. For example, a Nashorn-embedding application may prevent the spawning of threads from scripts or other resource-intensive operations that may be allowed by security manager.

      • Provide compatibility with Mozilla Rhino's ClassShutters. Nashorn's ClassFilter API will not have same package, class, or method names as that of the Mozilla Rhino engine. The proposed Nashorn API is only conceptually similar to the Rhino's ClassShutter API.


      There are several global objects such as Packages, java, org, com, javax, javafx, org, net, JavaImporter and Java that provide easy access to Java classes from JavaScript code in Nashorn. With a security manager on, the expected Java security policy is enforced: Anonymous scripts are granted the same permissions as are granted to untrusted classes, or else a script loaded from a URL is granted the permissions associated with that URL.

      When using Nashorn with the –no-java option, the above global package objects are not provided, effectively preventing all Java package and class access from scripts. A script has either complete Java access, subject to security restrictions, or else no access with –no-java.

      The Rhino JavaScript engine provides finer-grained access control via the user defined ClassShutter class. Rhino-embedding Java applications can choose to expose a subset of Java classes to scripts. Nashorn should provide similar fine-grained Java API.

      Server-side JavaScript frameworks are an important target for the Nashorn script engine. Such frameworks may occasionally have to run scripts from untrusted sources and therefore limit access to Java APIs. While security-manager based sandboxing helps here, Nashorn-embedding server-side applications often need finer control. An API should make it possible to restrict Java class access to a subset of Java classes.


      A new interface, jdk.nashorn.api.scripting.ClassFilter will be defined. Nashorn-embedding applications such as server-side JavaScript frameworks may choose to implement ClassFilter. To provide a user-implemented ClassFilter to Nashorn, the client application will have to use the Nashorn-specific API to instantiate the Nashorn script engine.

      New API added to class jdk.nashorn.api.scripting.NashornScriptEngineFactory:

        * Create a new Script engine initialized by given class filter.
        * @return newly created script engine.
        * @throws NullPointerException if {@code classFilter} is {@code null}
        * @throws SecurityException
        *         if the security manager's {@code checkPermission}
        *         denies {@code RuntimePermission("nashorn.setConfig")}
       public ScriptEngine getScriptEngine(final ClassFilter classFilter)
       * Create a new Script engine initialized by given arguments.
       * @param args arguments array passed to script engine.
       * @param appLoader class loader to be used as script "application" class loader.
       * @param classFilter class filter to use.
       * @return newly created script engine.
       * @throws NullPointerException if {@code args} or {@code classFilter} is {@code null}
       * @throws SecurityException
       *         if the security manager's {@code checkPermission}
       *         denies {@code RuntimePermission("nashorn.setConfig")}
       public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader, final ClassFilter classFilter)

      New interface jdk.nashorn.api.scripting.ClassFilter:

      public interface ClassFilter {
            * Should the Java class of the specified name be exposed to scripts?
            * @param className is the fully qualified name of the java class being checked. This will not be null. Only non-array class names will be passed.
            * @return true if the java class can be exposed to scripts false otherwise
           public boolean exposeToScripts(String className);

      The Nashorn script interface to Java packages and classes is via the Packages object and the Java.type function. The Packages object allows Java classes and packages be accessed via the familiar "dot-dot" syntax. The Java.type function accepts the string name of a fully-qualified Java type and returns the corresponding Class object. Both of these APIs will check if there is a class filter set in the Nashorn script engine. If a class filter is present then the interface will query it to see if the class can be exposed to scripts. If the filter returns false then the Java.type function will throw ClassNotFoundException and the Packages API will treat a dotted name as a package name rather than a class name.


      var Vector = java.util.Vector;
      var Thread = Java.type(`java.lang.Thread`);

      If the class filter prevents access to java.util.Vector and java.lang.Thread then in the first line java.util.Vector will be treated as a package name instead of being resolved as a Java class, and in the second line the invocation of Java.type will result in a ClassNotFoundException being thrown.

      If a security manager is present then Nashorn allows a script to use the Java reflection APIs (i.e., java.lang.reflect and java.lang.invoke) only if the script has the nashorn.javaReflection run-time permission. If a class filter is present then Nashorn will prevent access to reflective APIs even when a security manager is not present. It does not make sense to use a class filter if reflection is available, because a script can use the Class.forName(String) method to circumvent the class filter.


      There are over 1,000 Nashorn script tests in the Nashorn repository. There are tests accessing the javax.script API as well as the Nashorn-specific APIs in the jdk.nashorn.api.scripting package. The latter will be extended to include class-filter tests.

      Risks and Assumptions

      The new API will be added to the existing jdk.nashorn.api.scripting package. Users will have to use this non-standard, JDK-specific API in order to implement class filters.


        Issue Links



              sundar Sundararajan Athijegannathan
              sundar Sundararajan Athijegannathan
              Sundararajan Athijegannathan Sundararajan Athijegannathan
              Jim Laskey
              Brian Goetz
              0 Vote for this issue
              13 Start watching this issue