Secure Nashorn JS Execution

前端 未结 9 1263
故里飘歌
故里飘歌 2020-12-04 12:07

How can I securely execute some user supplied JS code using Java8 Nashorn?

The script extends some computations for some servlet based reports. The app has many diff

相关标签:
9条回答
  • 2020-12-04 12:42

    So far as I can tell, you can't sandbox Nashorn. An untrusted user can execute the "Additional Nashorn Built-In Functions" listed here:

    https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/shell.html

    which include "quit()". I tested it; it exits the JVM entirely.

    (As an aside, in my setup the global objects, $ENV, $ARG, did not work, which is good.)

    If I'm wrong about this, someone please leave a comment.

    0 讨论(0)
  • 2020-12-04 12:43

    I've researched ways of allowing users to write a simple script in a sandbox that is allowed access to some basic objects provided by my application (in the same way Google Apps Script works). My conclusion was that this is easier/better documented with Rhino than with Nashorn. You can:

    1. Define a class-shutter to avoid access to other classes: http://codeutopia.net/blog/2009/01/02/sandboxing-rhino-in-java/

    2. Limit the number of instructions to avoid endess-loops with observeInstructionCount: http://www-archive.mozilla.org/rhino/apidocs/org/mozilla/javascript/ContextFactory.html

    However be warned that with untrusted users this is not enough, because they can still (by accident or on purpose) allocate a hugh amount of memory, causing your JVM to throw an OutOfMemoryError. I have not found a safe solution to this last point yet.

    0 讨论(0)
  • 2020-12-04 13:03

    I asked this question on the Nashorn mailing list a while back:

    Are there any recommendations for the best way to restrict the classes that Nashorn scripts can create to a whitelist? Or is the approach the same as any JSR223 engine (custom classloader on the ScriptEngineManager constructor)?

    And got this answer from one of the Nashorn devs:

    Hi,

    • Nashorn already filters classes - only public classes of non-sensitive packages (packages listed in package.access security property aka 'sensitive'). Package access check is done from a no-permissions context. i.e., whatever package that can be accessed from a no-permissions class are only allowed.

    • Nashorn filters Java reflective and jsr292 access - unless script has RuntimePermission("nashorn.JavaReflection"), the script wont be able to do reflection.

    • The above two require running with SecurityManager enabled. Under no security manager, the above filtering won't apply.

    • You could remove global Java.type function and Packages object (+ com,edu,java,javafx,javax,org,JavaImporter) in global scope and/or replace those with whatever filtering functions that you implement. Because, these are the only entry points to Java access from script, customizing these functions => filtering Java access from scripts.

    • There is an undocumented option (right now used only to run test262 tests) "--no-java" of nashorn shell that does the above for you. i.e., Nashorn won't initialize Java hooks in global scope.

    • JSR223 does not provide any standards based hook to pass a custom class loader. This may have to be addressed in a (possible) future update of jsr223.

    Hope this helps,

    -Sundar

    0 讨论(0)
提交回复
热议问题