I'm currently working on a Java project where we aim to allow end-users to define variables that are calculated based on a set of given primitive types or string variables. Once all the given variables are assigned specific values, the calculations will be executed, and the resulting calculated variables will be sent back to Java.
As part of this project, I'm exploring different methods for users to define their calculations. The current idea is to allow users to write JavaScript code that will be interpreted and executed within the Java program. There are two main ways to achieve this: using the javax.scripting API or GraalVM/Truffle. In both cases, the process would involve:
- Passing the given variables into the script. This can be done using `ScriptEngine.put` in javax.scripting or `Value.putMember` in Graal/Truffle.
- Allowing the end-user to define variables in the global context without any naming conflicts with existing Java variables. Users can set the values of these variables directly (as constants or based on calculations involving other variables) or by defining objects and functions to handle the calculations.
- Executing the script once all given variables have been assigned values.
- Retrieving all variables defined in the global context by the script and sending them back to Java. This can be achieved using `ScriptEngine.get` in javax.scripting or `Value.getMember` in Graal/Truffle.
NOTE: The script will not have access to any Java classes or methods. In javax.scripting, this can be enforced by checking for the string `Java.type` in the script. In Graal/Truffle, the default `Context` with `allowAllAccess=false` will be used.
While there are many resources available on JavaScript security issues and how to mitigate them, I don't see any immediate concerns in this project scenario. However, as I'm not very familiar with JavaScript beyond basic calculations, I'm seeking advice on potential security risks in this setup.
Why I believe there are no security issues in this scenario:
This setup involves pure JavaScript, which does not have capabilities for actions like creating Blobs or accessing file systems. JavaScript is confined to manipulating data within its sandbox without the ability for actions like file access, threading, or streams. This aligns with the definition of ECMAScript as described in the specification.
Our sandbox only contains harmless input data (primitive types and strings) for the script to work with, and the resulting variables generated by the script are safely retrieved for use in the Java program.