title: Security risks when evaluating user input as JavaScript in Java
body: <p>I want to give the user the possibility of writing symbolic maths formulas which are later evaluated with certain values.</p>
  <p>The user might - for example - want to enter some formula <code>a * (b + 1)</code> where <code>a</code> and <code>b</code> may be different upon each evaluation. My approach so far was using the built in JavaScript engine in Java but as I read through <a href="https://docs.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/" rel="nofollow noreferrer">this tutorial on scripting</a>, I realized that the engine is actually really powerful.</p>
  <p>The formulas are stored in configuration files, so someone might send such a configuration file to another user, which would then be executed on their machine.
  Unfortunately I don't know JavaScript, so I don't know if the user could actually inject any seriously malicious code.</p>
  <p>The formula above would be stored as a <code>JavaScriptFormulaProcessor</code> object like this:</p>
  <pre><code>JavaScriptFormulaProcessor processor =
          new JavaScriptFormulaProcessor(&quot;a * (b + 1)&quot;, &quot;a&quot;, &quot;b&quot;);
  </code></pre>
  <p><strong>Initializing the engine:</strong></p>
  <pre><code>public JavaScriptFormulaProcessor(String formula, String... variableNames) throws ScriptException {
      ScriptEngine engine = new ScriptEngineManager().getEngineByName(&quot;JavaScript&quot;);
      StringBuilder builder = new StringBuilder(variableNames[0]);
      for (int i = 1; i &lt; variableNames.length; i++) {
          builder.append(&quot;, &quot;).append(variableNames[i]);
      }
      String script = &quot;function f(&quot;+builder.toString()+&quot;) { return &quot;+formula+&quot;}&quot;;
      engine.eval(script);
      invocable = (Invocable) engine;
  }
  </code></pre>
  <p><strong>Executing the function:</strong></p>
  <pre><code>public void execute(Number[] functionInputs) throws ScriptException {
      try {
          Object result = invocable.invokeFunction(&quot;f&quot;, functionInputs);
          // process result..
      } catch (NoSuchMethodException e) {
          throw new RuntimeException(e); // should actually never be thrown..
      }
  }
  </code></pre>
  <p>Does this code create an attack vector for my application? Bonus question: if yes, any better suggestions?</p>