From d664aa6d6add71d2b0d9287dcae665f8ea7df91f Mon Sep 17 00:00:00 2001
From: luchua-bc
Date: Wed, 5 May 2021 14:21:52 +0000
Subject: [PATCH] Include more scenarios and update qldoc
---
.../CWE/CWE-094/ScriptInjection.qhelp | 15 ++-
.../Security/CWE/CWE-094/ScriptInjection.ql | 86 +++++++++++---
.../security/CWE-094/RhinoServlet.java | 16 +++
.../security/CWE-094/ScriptEngineTest.java | 39 +++++-
.../security/CWE-094/ScriptInjection.expected | 64 ++++++----
.../mozilla/javascript/CompilerEnvirons.java | 12 ++
.../org/mozilla/javascript/Context.java | 72 +++++++++++
.../javascript/DefiningClassLoader.java | 36 ++++++
.../org/mozilla/javascript/Function.java | 46 +++++++
.../javascript/GeneratedClassLoader.java | 34 ++++++
.../org/mozilla/javascript/Script.java | 41 +++++++
.../javascript/optimizer/ClassCompiler.java | 112 ++++++++++++++++++
.../scriptengine/javax/script/Bindings.java | 14 +++
.../scriptengine/javax/script/Compilable.java | 9 ++
.../javax/script/CompiledScript.java | 17 +++
.../javax/script/ScriptEngine.java | 2 +
.../javax/script/ScriptEngineFactory.java | 7 +-
.../nashorn/api/scripting/ClassFilter.java | 5 +
.../api/scripting/NashornScriptEngine.java | 27 ++++-
.../scripting/NashornScriptEngineFactory.java | 34 +++++-
20 files changed, 633 insertions(+), 55 deletions(-)
create mode 100644 java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/CompilerEnvirons.java
create mode 100644 java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/DefiningClassLoader.java
create mode 100644 java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/Function.java
create mode 100644 java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/GeneratedClassLoader.java
create mode 100644 java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/Script.java
create mode 100644 java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/optimizer/ClassCompiler.java
create mode 100644 java/ql/test/stubs/scriptengine/javax/script/Bindings.java
create mode 100644 java/ql/test/stubs/scriptengine/javax/script/Compilable.java
create mode 100644 java/ql/test/stubs/scriptengine/javax/script/CompiledScript.java
create mode 100644 java/ql/test/stubs/scriptengine/jdk/nashorn/api/scripting/ClassFilter.java
diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/ScriptInjection.qhelp b/java/ql/src/experimental/Security/CWE/CWE-094/ScriptInjection.qhelp
index ddc011fa658..586304ebb7c 100644
--- a/java/ql/src/experimental/Security/CWE/CWE-094/ScriptInjection.qhelp
+++ b/java/ql/src/experimental/Security/CWE/CWE-094/ScriptInjection.qhelp
@@ -4,7 +4,7 @@
-The JavaScript Engine API has been available since the release of Java 6, which allows
+
The Java Scripting API has been available since the release of Java 6, which allows
applications to interact with scripts written in languages such as JavaScript. It serves
as an embedded scripting engine inside Java applications which allows Java-to-JavaScript
interoperability and provides a seamless integration between the two languages. If an
@@ -13,11 +13,11 @@
-In general, including user input in a JavaScript Engine expression should be avoided.
+
In general, including user input in a Java Script Engine expression should be avoided.
If user input must be included in the expression, it should be then evaluated in a safe
- context that doesn't allow arbitrary code invocation. Use "Cloudbees Rhino Sandbox" or
- sandboxing with SecurityManager or use graalvm
- instead.
+ context that doesn't allow arbitrary code invocation. Use "Cloudbees Rhino Sandbox" or
+ sandboxing with SecurityManager, which will be deprecated in a future release, or use
+ GraalVM instead.
@@ -36,6 +36,9 @@
CERT coding standard: ScriptEngine code injection
+
+GraalVM: Secure by Default
+
Mozilla Rhino: Rhino: JavaScript in Java
@@ -43,7 +46,7 @@ CERT coding standard: A sandbox to execute JavaScript code with Rhino in Java
- GuardRails: Code Injection
+ GuardRails: Code Injection
diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/ScriptInjection.ql b/java/ql/src/experimental/Security/CWE/CWE-094/ScriptInjection.ql
index 35f73fd5270..d4f8cfa5370 100644
--- a/java/ql/src/experimental/Security/CWE/CWE-094/ScriptInjection.ql
+++ b/java/ql/src/experimental/Security/CWE/CWE-094/ScriptInjection.ql
@@ -1,7 +1,7 @@
/**
- * @name Injection in JavaScript Engine
+ * @name Injection in Java Script Engine
* @description Evaluation of a user-controlled malicious JavaScript or Java expression in
- * JavaScript Engine may lead to remote code execution.
+ * Java Script Engine may lead to remote code execution.
* @kind path-problem
* @problem.severity error
* @precision high
@@ -14,31 +14,62 @@ import java
import semmle.code.java.dataflow.FlowSources
import DataFlow::PathGraph
+/** A method of ScriptEngine that allows code injection. */
class ScriptEngineMethod extends Method {
ScriptEngineMethod() {
this.getDeclaringType().getASupertype*().hasQualifiedName("javax.script", "ScriptEngine") and
this.hasName("eval")
+ or
+ this.getDeclaringType().getASupertype*().hasQualifiedName("javax.script", "Compilable") and
+ this.hasName("compile")
+ or
+ this.getDeclaringType().getASupertype*().hasQualifiedName("javax.script", "ScriptEngineFactory") and
+ this.hasName(["getProgram", "getMethodCallSyntax"])
}
}
-/** The context class `org.mozilla.javascript.Context` of Rhino JavaScript Engine. */
+/** The context class `org.mozilla.javascript.Context` of Rhino Java Script Engine. */
class RhinoContext extends RefType {
RhinoContext() { this.hasQualifiedName("org.mozilla.javascript", "Context") }
}
-/**
- * A method that evaluates a Rhino expression.
- */
+/** A method that evaluates a Rhino expression with `org.mozilla.javascript.Context`. */
class RhinoEvaluateExpressionMethod extends Method {
RhinoEvaluateExpressionMethod() {
this.getDeclaringType().getAnAncestor*() instanceof RhinoContext and
- (
- hasName("evaluateString") or
- hasName("evaluateReader")
- )
+ this.hasName([
+ "evaluateString", "evaluateReader", "compileFunction", "compileReader", "compileString"
+ ])
}
}
+/**
+ * A method that compiles a Rhino expression with
+ * `org.mozilla.javascript.optimizer.ClassCompiler`.
+ */
+class RhinoCompileClassMethod extends Method {
+ RhinoCompileClassMethod() {
+ this.getDeclaringType()
+ .getASupertype*()
+ .hasQualifiedName("org.mozilla.javascript.optimizer", "ClassCompiler") and
+ this.hasName("compileToClassFiles")
+ }
+}
+
+/**
+ * A method that defines a Java class from a Rhino expression with
+ * `org.mozilla.javascript.GeneratedClassLoader`.
+ */
+class RhinoDefineClassMethod extends Method {
+ RhinoDefineClassMethod() {
+ this.getDeclaringType()
+ .getASupertype*()
+ .hasQualifiedName("org.mozilla.javascript", "GeneratedClassLoader") and
+ this.hasName("defineClass")
+ }
+}
+
+/** Holds if `ma` is a method access of `ScriptEngineMethod`. */
predicate scriptEngine(MethodAccess ma, Expr sink) {
exists(Method m | m = ma.getMethod() |
m instanceof ScriptEngineMethod and
@@ -47,11 +78,17 @@ predicate scriptEngine(MethodAccess ma, Expr sink) {
}
/**
- * Holds if `ma` has Rhino code injection vulnerabilities.
+ * Holds if a Rhino expression evaluation method has the code injection vulnerability.
*/
predicate evaluateRhinoExpression(MethodAccess ma, Expr sink) {
exists(RhinoEvaluateExpressionMethod m | m = ma.getMethod() |
- sink = ma.getArgument(1) and // The second argument is the JavaScript or Java input
+ (
+ sink = ma.getArgument(1) and // The second argument is the JavaScript or Java input
+ not ma.getMethod().getName() = "compileReader"
+ or
+ sink = ma.getArgument(0) and // The first argument is the input reader
+ ma.getMethod().getName() = "compileReader"
+ ) and
not exists(MethodAccess ca |
(
ca.getMethod().hasName("initSafeStandardObjects") // safe mode
@@ -63,15 +100,34 @@ predicate evaluateRhinoExpression(MethodAccess ma, Expr sink) {
)
}
+/**
+ * Holds if a Rhino expression compilation method has the code injection vulnerability.
+ */
+predicate compileScript(MethodAccess ma, Expr sink) {
+ exists(RhinoCompileClassMethod m | m = ma.getMethod() | sink = ma.getArgument(0))
+}
+
+/**
+ * Holds if a Rhino class loading method has the code injection vulnerability.
+ */
+predicate defineClass(MethodAccess ma, Expr sink) {
+ exists(RhinoDefineClassMethod m | m = ma.getMethod() | sink = ma.getArgument(1))
+}
+
+/** A sink of script injection. */
class ScriptInjectionSink extends DataFlow::ExprNode {
ScriptInjectionSink() {
scriptEngine(_, this.getExpr()) or
- evaluateRhinoExpression(_, this.getExpr())
+ evaluateRhinoExpression(_, this.getExpr()) or
+ compileScript(_, this.getExpr()) or
+ defineClass(_, this.getExpr())
}
MethodAccess getMethodAccess() {
scriptEngine(result, this.getExpr()) or
- evaluateRhinoExpression(result, this.getExpr())
+ evaluateRhinoExpression(result, this.getExpr()) or
+ compileScript(result, this.getExpr()) or
+ defineClass(result, this.getExpr())
}
}
@@ -90,4 +146,4 @@ class ScriptInjectionConfiguration extends TaintTracking::Configuration {
from DataFlow::PathNode source, DataFlow::PathNode sink, ScriptInjectionConfiguration conf
where conf.hasFlowPath(source, sink)
select sink.getNode().(ScriptInjectionSink).getMethodAccess(), source, sink,
- "JavaScript Engine evaluate $@.", source.getNode(), "user input"
+ "Java Script Engine evaluate $@.", source.getNode(), "user input"
diff --git a/java/ql/test/experimental/query-tests/security/CWE-094/RhinoServlet.java b/java/ql/test/experimental/query-tests/security/CWE-094/RhinoServlet.java
index f6f529785cc..2c863b6f62f 100644
--- a/java/ql/test/experimental/query-tests/security/CWE-094/RhinoServlet.java
+++ b/java/ql/test/experimental/query-tests/security/CWE-094/RhinoServlet.java
@@ -5,9 +5,12 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.mozilla.javascript.ClassShutter;
+import org.mozilla.javascript.CompilerEnvirons;
import org.mozilla.javascript.Context;
+import org.mozilla.javascript.DefiningClassLoader;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.RhinoException;
+import org.mozilla.javascript.optimizer.ClassCompiler;
/**
* Servlet implementation class RhinoServlet
@@ -75,4 +78,17 @@ public class RhinoServlet extends HttpServlet {
Context.exit();
}
}
+
+ // BAD: allow arbitrary code to be compiled for subsequent execution
+ protected void doGet2(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ String code = request.getParameter("code");
+ ClassCompiler compiler = new ClassCompiler(new CompilerEnvirons());
+ Object[] objs = compiler.compileToClassFiles(code, "/sourceLocation", 1, "mainClassName");
+ }
+
+ // BAD: allow arbitrary code to be loaded for subsequent execution
+ protected void doPost2(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ String code = request.getParameter("code");
+ Class clazz = new DefiningClassLoader().defineClass("Powerfunc", code.getBytes());
+ }
}
diff --git a/java/ql/test/experimental/query-tests/security/CWE-094/ScriptEngineTest.java b/java/ql/test/experimental/query-tests/security/CWE-094/ScriptEngineTest.java
index e04ec615f30..42d9cad6e64 100755
--- a/java/ql/test/experimental/query-tests/security/CWE-094/ScriptEngineTest.java
+++ b/java/ql/test/experimental/query-tests/security/CWE-094/ScriptEngineTest.java
@@ -33,26 +33,53 @@ public class ScriptEngineTest {
MyCustomScriptEngine engine = (MyCustomScriptEngine) factory.getScriptEngine(new String[] { "-scripting" });
Object result = engine.eval(input);
}
+
+ public void testScriptEngineCompilable(String input) throws ScriptException {
+ NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
+ Compilable engine = (Compilable) factory.getScriptEngine(new String[] { "-scripting" });
+ CompiledScript script = engine.compile(input);
+ Object result = script.eval();
+ }
+
+ public void testScriptEngineGetProgram(String input) throws ScriptException {
+ ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
+ ScriptEngine engine = scriptEngineManager.getEngineByName("nashorn");
+ String program = engine.getFactory().getProgram(input);
+ Object result = engine.eval(program);
+ }
public static void main(String[] args) throws ScriptException {
new ScriptEngineTest().testWithScriptEngineReference(args[0]);
new ScriptEngineTest().testNashornWithScriptEngineReference(args[0]);
new ScriptEngineTest().testNashornWithNashornScriptEngineReference(args[0]);
new ScriptEngineTest().testCustomScriptEngineReference(args[0]);
+ new ScriptEngineTest().testScriptEngineCompilable(args[0]);
+ new ScriptEngineTest().testScriptEngineGetProgram(args[0]);
}
private static class MyCustomScriptEngine extends AbstractScriptEngine {
- public Object eval(String var1) throws ScriptException {
- return null;
- }
+ public Object eval(String var1) throws ScriptException { return null; }
+
+ @Override
+ public ScriptEngineFactory getFactory() { return null; }
}
private static class MyCustomFactory implements ScriptEngineFactory {
public MyCustomFactory() {
- }
-
- public ScriptEngine getScriptEngine() { return null; }
+ }
+
+ @Override
+ public ScriptEngine getScriptEngine() { return null; }
public ScriptEngine getScriptEngine(String... args) { return null; }
+
+ @Override
+ public String getEngineName() { return null; }
+
+ @Override
+ public String getMethodCallSyntax(final String obj, final String method, final String... args) { return null; }
+
+ @Override
+ public String getProgram(final String... statements) { return null; }
}
}
diff --git a/java/ql/test/experimental/query-tests/security/CWE-094/ScriptInjection.expected b/java/ql/test/experimental/query-tests/security/CWE-094/ScriptInjection.expected
index 452c2d70c57..0c191a4f579 100644
--- a/java/ql/test/experimental/query-tests/security/CWE-094/ScriptInjection.expected
+++ b/java/ql/test/experimental/query-tests/security/CWE-094/ScriptInjection.expected
@@ -1,20 +1,32 @@
edges
-| RhinoServlet.java:25:23:25:50 | getParameter(...) : String | RhinoServlet.java:29:55:29:58 | code |
+| RhinoServlet.java:28:23:28:50 | getParameter(...) : String | RhinoServlet.java:32:55:32:58 | code |
+| RhinoServlet.java:84:23:84:50 | getParameter(...) : String | RhinoServlet.java:86:54:86:57 | code |
+| RhinoServlet.java:91:23:91:50 | getParameter(...) : String | RhinoServlet.java:92:74:92:88 | getBytes(...) |
| ScriptEngineTest.java:8:44:8:55 | input : String | ScriptEngineTest.java:12:37:12:41 | input |
| ScriptEngineTest.java:15:51:15:62 | input : String | ScriptEngineTest.java:19:31:19:35 | input |
| ScriptEngineTest.java:23:58:23:69 | input : String | ScriptEngineTest.java:27:31:27:35 | input |
| ScriptEngineTest.java:30:46:30:57 | input : String | ScriptEngineTest.java:34:31:34:35 | input |
-| ScriptEngineTest.java:37:26:37:38 | args : String[] | ScriptEngineTest.java:38:56:38:62 | ...[...] : String |
-| ScriptEngineTest.java:37:26:37:38 | args : String[] | ScriptEngineTest.java:39:63:39:69 | ...[...] : String |
-| ScriptEngineTest.java:37:26:37:38 | args : String[] | ScriptEngineTest.java:40:70:40:76 | ...[...] : String |
-| ScriptEngineTest.java:37:26:37:38 | args : String[] | ScriptEngineTest.java:41:58:41:64 | ...[...] : String |
-| ScriptEngineTest.java:38:56:38:62 | ...[...] : String | ScriptEngineTest.java:8:44:8:55 | input : String |
-| ScriptEngineTest.java:39:63:39:69 | ...[...] : String | ScriptEngineTest.java:15:51:15:62 | input : String |
-| ScriptEngineTest.java:40:70:40:76 | ...[...] : String | ScriptEngineTest.java:23:58:23:69 | input : String |
-| ScriptEngineTest.java:41:58:41:64 | ...[...] : String | ScriptEngineTest.java:30:46:30:57 | input : String |
+| ScriptEngineTest.java:37:41:37:52 | input : String | ScriptEngineTest.java:40:42:40:46 | input |
+| ScriptEngineTest.java:44:41:44:52 | input : String | ScriptEngineTest.java:47:51:47:55 | input |
+| ScriptEngineTest.java:51:26:51:38 | args : String[] | ScriptEngineTest.java:52:56:52:62 | ...[...] : String |
+| ScriptEngineTest.java:51:26:51:38 | args : String[] | ScriptEngineTest.java:53:63:53:69 | ...[...] : String |
+| ScriptEngineTest.java:51:26:51:38 | args : String[] | ScriptEngineTest.java:54:70:54:76 | ...[...] : String |
+| ScriptEngineTest.java:51:26:51:38 | args : String[] | ScriptEngineTest.java:55:58:55:64 | ...[...] : String |
+| ScriptEngineTest.java:51:26:51:38 | args : String[] | ScriptEngineTest.java:56:53:56:59 | ...[...] : String |
+| ScriptEngineTest.java:51:26:51:38 | args : String[] | ScriptEngineTest.java:57:53:57:59 | ...[...] : String |
+| ScriptEngineTest.java:52:56:52:62 | ...[...] : String | ScriptEngineTest.java:8:44:8:55 | input : String |
+| ScriptEngineTest.java:53:63:53:69 | ...[...] : String | ScriptEngineTest.java:15:51:15:62 | input : String |
+| ScriptEngineTest.java:54:70:54:76 | ...[...] : String | ScriptEngineTest.java:23:58:23:69 | input : String |
+| ScriptEngineTest.java:55:58:55:64 | ...[...] : String | ScriptEngineTest.java:30:46:30:57 | input : String |
+| ScriptEngineTest.java:56:53:56:59 | ...[...] : String | ScriptEngineTest.java:37:41:37:52 | input : String |
+| ScriptEngineTest.java:57:53:57:59 | ...[...] : String | ScriptEngineTest.java:44:41:44:52 | input : String |
nodes
-| RhinoServlet.java:25:23:25:50 | getParameter(...) : String | semmle.label | getParameter(...) : String |
-| RhinoServlet.java:29:55:29:58 | code | semmle.label | code |
+| RhinoServlet.java:28:23:28:50 | getParameter(...) : String | semmle.label | getParameter(...) : String |
+| RhinoServlet.java:32:55:32:58 | code | semmle.label | code |
+| RhinoServlet.java:84:23:84:50 | getParameter(...) : String | semmle.label | getParameter(...) : String |
+| RhinoServlet.java:86:54:86:57 | code | semmle.label | code |
+| RhinoServlet.java:91:23:91:50 | getParameter(...) : String | semmle.label | getParameter(...) : String |
+| RhinoServlet.java:92:74:92:88 | getBytes(...) | semmle.label | getBytes(...) |
| ScriptEngineTest.java:8:44:8:55 | input : String | semmle.label | input : String |
| ScriptEngineTest.java:12:37:12:41 | input | semmle.label | input |
| ScriptEngineTest.java:15:51:15:62 | input : String | semmle.label | input : String |
@@ -23,14 +35,24 @@ nodes
| ScriptEngineTest.java:27:31:27:35 | input | semmle.label | input |
| ScriptEngineTest.java:30:46:30:57 | input : String | semmle.label | input : String |
| ScriptEngineTest.java:34:31:34:35 | input | semmle.label | input |
-| ScriptEngineTest.java:37:26:37:38 | args : String[] | semmle.label | args : String[] |
-| ScriptEngineTest.java:38:56:38:62 | ...[...] : String | semmle.label | ...[...] : String |
-| ScriptEngineTest.java:39:63:39:69 | ...[...] : String | semmle.label | ...[...] : String |
-| ScriptEngineTest.java:40:70:40:76 | ...[...] : String | semmle.label | ...[...] : String |
-| ScriptEngineTest.java:41:58:41:64 | ...[...] : String | semmle.label | ...[...] : String |
+| ScriptEngineTest.java:37:41:37:52 | input : String | semmle.label | input : String |
+| ScriptEngineTest.java:40:42:40:46 | input | semmle.label | input |
+| ScriptEngineTest.java:44:41:44:52 | input : String | semmle.label | input : String |
+| ScriptEngineTest.java:47:51:47:55 | input | semmle.label | input |
+| ScriptEngineTest.java:51:26:51:38 | args : String[] | semmle.label | args : String[] |
+| ScriptEngineTest.java:52:56:52:62 | ...[...] : String | semmle.label | ...[...] : String |
+| ScriptEngineTest.java:53:63:53:69 | ...[...] : String | semmle.label | ...[...] : String |
+| ScriptEngineTest.java:54:70:54:76 | ...[...] : String | semmle.label | ...[...] : String |
+| ScriptEngineTest.java:55:58:55:64 | ...[...] : String | semmle.label | ...[...] : String |
+| ScriptEngineTest.java:56:53:56:59 | ...[...] : String | semmle.label | ...[...] : String |
+| ScriptEngineTest.java:57:53:57:59 | ...[...] : String | semmle.label | ...[...] : String |
#select
-| RhinoServlet.java:29:29:29:78 | evaluateString(...) | RhinoServlet.java:25:23:25:50 | getParameter(...) : String | RhinoServlet.java:29:55:29:58 | code | JavaScript Engine evaluate $@. | RhinoServlet.java:25:23:25:50 | getParameter(...) | user input |
-| ScriptEngineTest.java:12:19:12:42 | eval(...) | ScriptEngineTest.java:37:26:37:38 | args : String[] | ScriptEngineTest.java:12:37:12:41 | input | JavaScript Engine evaluate $@. | ScriptEngineTest.java:37:26:37:38 | args | user input |
-| ScriptEngineTest.java:19:19:19:36 | eval(...) | ScriptEngineTest.java:37:26:37:38 | args : String[] | ScriptEngineTest.java:19:31:19:35 | input | JavaScript Engine evaluate $@. | ScriptEngineTest.java:37:26:37:38 | args | user input |
-| ScriptEngineTest.java:27:19:27:36 | eval(...) | ScriptEngineTest.java:37:26:37:38 | args : String[] | ScriptEngineTest.java:27:31:27:35 | input | JavaScript Engine evaluate $@. | ScriptEngineTest.java:37:26:37:38 | args | user input |
-| ScriptEngineTest.java:34:19:34:36 | eval(...) | ScriptEngineTest.java:37:26:37:38 | args : String[] | ScriptEngineTest.java:34:31:34:35 | input | JavaScript Engine evaluate $@. | ScriptEngineTest.java:37:26:37:38 | args | user input |
+| RhinoServlet.java:32:29:32:78 | evaluateString(...) | RhinoServlet.java:28:23:28:50 | getParameter(...) : String | RhinoServlet.java:32:55:32:58 | code | Java Script Engine evaluate $@. | RhinoServlet.java:28:23:28:50 | getParameter(...) | user input |
+| RhinoServlet.java:86:25:86:97 | compileToClassFiles(...) | RhinoServlet.java:84:23:84:50 | getParameter(...) : String | RhinoServlet.java:86:54:86:57 | code | Java Script Engine evaluate $@. | RhinoServlet.java:84:23:84:50 | getParameter(...) | user input |
+| RhinoServlet.java:92:23:92:89 | defineClass(...) | RhinoServlet.java:91:23:91:50 | getParameter(...) : String | RhinoServlet.java:92:74:92:88 | getBytes(...) | Java Script Engine evaluate $@. | RhinoServlet.java:91:23:91:50 | getParameter(...) | user input |
+| ScriptEngineTest.java:12:19:12:42 | eval(...) | ScriptEngineTest.java:51:26:51:38 | args : String[] | ScriptEngineTest.java:12:37:12:41 | input | Java Script Engine evaluate $@. | ScriptEngineTest.java:51:26:51:38 | args | user input |
+| ScriptEngineTest.java:19:19:19:36 | eval(...) | ScriptEngineTest.java:51:26:51:38 | args : String[] | ScriptEngineTest.java:19:31:19:35 | input | Java Script Engine evaluate $@. | ScriptEngineTest.java:51:26:51:38 | args | user input |
+| ScriptEngineTest.java:27:19:27:36 | eval(...) | ScriptEngineTest.java:51:26:51:38 | args : String[] | ScriptEngineTest.java:27:31:27:35 | input | Java Script Engine evaluate $@. | ScriptEngineTest.java:51:26:51:38 | args | user input |
+| ScriptEngineTest.java:34:19:34:36 | eval(...) | ScriptEngineTest.java:51:26:51:38 | args : String[] | ScriptEngineTest.java:34:31:34:35 | input | Java Script Engine evaluate $@. | ScriptEngineTest.java:51:26:51:38 | args | user input |
+| ScriptEngineTest.java:40:27:40:47 | compile(...) | ScriptEngineTest.java:51:26:51:38 | args : String[] | ScriptEngineTest.java:40:42:40:46 | input | Java Script Engine evaluate $@. | ScriptEngineTest.java:51:26:51:38 | args | user input |
+| ScriptEngineTest.java:47:20:47:56 | getProgram(...) | ScriptEngineTest.java:51:26:51:38 | args : String[] | ScriptEngineTest.java:47:51:47:55 | input | Java Script Engine evaluate $@. | ScriptEngineTest.java:51:26:51:38 | args | user input |
diff --git a/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/CompilerEnvirons.java b/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/CompilerEnvirons.java
new file mode 100644
index 00000000000..3cb0619499e
--- /dev/null
+++ b/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/CompilerEnvirons.java
@@ -0,0 +1,12 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+ package org.mozilla.javascript;
+
+ public class CompilerEnvirons {
+ public CompilerEnvirons() {
+ }
+ }
\ No newline at end of file
diff --git a/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/Context.java b/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/Context.java
index 57d30a3ab25..1bda212cfa4 100644
--- a/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/Context.java
+++ b/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/Context.java
@@ -480,6 +480,78 @@ public class Context
return null;
}
+ /**
+ * @deprecated
+ * @see #compileReader(Reader in, String sourceName, int lineno, Object securityDomain)
+ */
+ @Deprecated
+ public final Script compileReader(
+ Scriptable scope, Reader in, String sourceName, int lineno, Object securityDomain)
+ throws IOException {
+ return null;
+ }
+
+ /**
+ * Compiles the source in the given reader.
+ *
+ * Returns a script that may later be executed. Will consume all the source in the reader.
+ *
+ * @param in the input reader
+ * @param sourceName a string describing the source, such as a filename
+ * @param lineno the starting line number for reporting errors
+ * @param securityDomain an arbitrary object that specifies security information about the
+ * origin or owner of the script. For implementations that don't care about security, this
+ * value may be null.
+ * @return a script that may later be executed
+ * @exception IOException if an IOException was generated by the Reader
+ * @see org.mozilla.javascript.Script
+ */
+ public final Script compileReader(
+ Reader in, String sourceName, int lineno, Object securityDomain) throws IOException {
+ return null;
+ }
+
+ /**
+ * Compiles the source in the given string.
+ *
+ *
Returns a script that may later be executed.
+ *
+ * @param source the source string
+ * @param sourceName a string describing the source, such as a filename
+ * @param lineno the starting line number for reporting errors. Use 0 if the line number is
+ * unknown.
+ * @param securityDomain an arbitrary object that specifies security information about the
+ * origin or owner of the script. For implementations that don't care about security, this
+ * value may be null.
+ * @return a script that may later be executed
+ * @see org.mozilla.javascript.Script
+ */
+ public final Script compileString(
+ String source, String sourceName, int lineno, Object securityDomain) {
+ return null;
+ }
+
+ /**
+ * Compile a JavaScript function.
+ *
+ *
The function source must be a function definition as defined by ECMA (e.g., "function f(a)
+ * { return a; }").
+ *
+ * @param scope the scope to compile relative to
+ * @param source the function definition source
+ * @param sourceName a string describing the source, such as a filename
+ * @param lineno the starting line number
+ * @param securityDomain an arbitrary object that specifies security information about the
+ * origin or owner of the script. For implementations that don't care about security, this
+ * value may be null.
+ * @return a Function that may later be called
+ * @see org.mozilla.javascript.Function
+ */
+ public final Function compileFunction(
+ Scriptable scope, String source, String sourceName, int lineno, Object securityDomain) {
+ return null;
+ }
+
/**
* Convert the value to a JavaScript boolean value.
*
diff --git a/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/DefiningClassLoader.java b/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/DefiningClassLoader.java
new file mode 100644
index 00000000000..3819798c351
--- /dev/null
+++ b/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/DefiningClassLoader.java
@@ -0,0 +1,36 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+ package org.mozilla.javascript;
+
+ /**
+ * Load generated classes.
+ *
+ * @author Norris Boyd
+ */
+ public class DefiningClassLoader extends ClassLoader
+ implements GeneratedClassLoader
+ {
+ public DefiningClassLoader() {
+ }
+
+ public DefiningClassLoader(ClassLoader parentLoader) {
+ }
+
+ @Override
+ public Class> defineClass(String name, byte[] data) {
+ return null;
+ }
+
+ @Override
+ public void linkClass(Class> cl) {
+ }
+
+ @Override
+ public Class> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException
+ {
+ return null;
+ }
+ }
\ No newline at end of file
diff --git a/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/Function.java b/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/Function.java
new file mode 100644
index 00000000000..a35a7c2dfba
--- /dev/null
+++ b/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/Function.java
@@ -0,0 +1,46 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * This is interface that all functions in JavaScript must implement. The interface provides for
+ * calling functions and constructors.
+ *
+ * @see org.mozilla.javascript.Scriptable
+ * @author Norris Boyd
+ */
+public interface Function extends Scriptable {
+ /**
+ * Call the function.
+ *
+ *
Note that the array of arguments is not guaranteed to have length greater than 0.
+ *
+ * @param cx the current Context for this thread
+ * @param scope the scope to execute the function relative to. This is set to the value returned
+ * by getParentScope() except when the function is called from a closure.
+ * @param thisObj the JavaScript this object
+ * @param args the array of arguments
+ * @return the result of the call
+ */
+ Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args);
+
+ /**
+ * Call the function as a constructor.
+ *
+ *
This method is invoked by the runtime in order to satisfy a use of the JavaScript
+ * new operator. This method is expected to create a new object and return it.
+ *
+ * @param cx the current Context for this thread
+ * @param scope an enclosing scope of the caller except when the function is called from a
+ * closure.
+ * @param args the array of arguments
+ * @return the allocated object
+ */
+ Scriptable construct(Context cx, Scriptable scope, Object[] args);
+}
\ No newline at end of file
diff --git a/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/GeneratedClassLoader.java b/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/GeneratedClassLoader.java
new file mode 100644
index 00000000000..c7450862917
--- /dev/null
+++ b/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/GeneratedClassLoader.java
@@ -0,0 +1,34 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * Interface to define classes from generated byte code.
+ */
+public interface GeneratedClassLoader {
+
+ /**
+ * Define a new Java class.
+ * Classes created via this method should have the same class loader.
+ *
+ * @param name fully qualified class name
+ * @param data class byte code
+ * @return new class object
+ */
+ public Class> defineClass(String name, byte[] data);
+
+ /**
+ * Link the given class.
+ *
+ * @param cl Class instance returned from the previous call to
+ * {@link #defineClass(String, byte[])}
+ * @see java.lang.ClassLoader
+ */
+ public void linkClass(Class> cl);
+}
diff --git a/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/Script.java b/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/Script.java
new file mode 100644
index 00000000000..824dc0241c1
--- /dev/null
+++ b/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/Script.java
@@ -0,0 +1,41 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * All compiled scripts implement this interface.
+ *
+ * This class encapsulates script execution relative to an
+ * object scope.
+ * @since 1.3
+ * @author Norris Boyd
+ */
+
+public interface Script {
+
+ /**
+ * Execute the script.
+ *
+ * The script is executed in a particular runtime Context, which
+ * must be associated with the current thread.
+ * The script is executed relative to a scope--definitions and
+ * uses of global top-level variables and functions will access
+ * properties of the scope object. For compliant ECMA
+ * programs, the scope must be an object that has been initialized
+ * as a global object using Context.initStandardObjects.
+ *
+ *
+ * @param cx the Context associated with the current thread
+ * @param scope the scope to execute relative to
+ * @return the result of executing the script
+ * @see org.mozilla.javascript.Context#initStandardObjects()
+ */
+ public Object exec(Context cx, Scriptable scope);
+
+}
\ No newline at end of file
diff --git a/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/optimizer/ClassCompiler.java b/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/optimizer/ClassCompiler.java
new file mode 100644
index 00000000000..cb2332d3f61
--- /dev/null
+++ b/java/ql/test/experimental/stubs/rhino-1.7.13/org/mozilla/javascript/optimizer/ClassCompiler.java
@@ -0,0 +1,112 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+ package org.mozilla.javascript.optimizer;
+
+ import org.mozilla.javascript.CompilerEnvirons;
+
+ /**
+ * Generates class files from script sources.
+ *
+ * since 1.5 Release 5
+ * @author Igor Bukanov
+ */
+
+ public class ClassCompiler
+ {
+ /**
+ * Construct ClassCompiler that uses the specified compiler environment
+ * when generating classes.
+ */
+ public ClassCompiler(CompilerEnvirons compilerEnv)
+ {
+ }
+
+ /**
+ * Set the class name to use for main method implementation.
+ * The class must have a method matching
+ * public static void main(Script sc, String[] args), it will be
+ * called when main(String[] args) is called in the generated
+ * class. The class name should be fully qulified name and include the
+ * package name like in org.foo.Bar.
+ */
+ public void setMainMethodClass(String className)
+ {
+ }
+
+ /**
+ * Get the name of the class for main method implementation.
+ * @see #setMainMethodClass(String)
+ */
+ public String getMainMethodClass()
+ {
+ return null;
+ }
+
+ /**
+ * Get the compiler environment the compiler uses.
+ */
+ public CompilerEnvirons getCompilerEnv()
+ {
+ return null;
+ }
+
+ /**
+ * Get the class that the generated target will extend.
+ */
+ public Class> getTargetExtends()
+ {
+ return null;
+ }
+
+ /**
+ * Set the class that the generated target will extend.
+ *
+ * @param extendsClass the class it extends
+ */
+ public void setTargetExtends(Class> extendsClass)
+ {
+ }
+
+ /**
+ * Get the interfaces that the generated target will implement.
+ */
+ public Class>[] getTargetImplements()
+ {
+ return null;
+ }
+
+ /**
+ * Set the interfaces that the generated target will implement.
+ *
+ * @param implementsClasses an array of Class objects, one for each
+ * interface the target will extend
+ */
+ public void setTargetImplements(Class>[] implementsClasses)
+ {
+ }
+
+ /**
+ * Compile JavaScript source into one or more Java class files.
+ * The first compiled class will have name mainClassName.
+ * If the results of {@link #getTargetExtends()} or
+ * {@link #getTargetImplements()} are not null, then the first compiled
+ * class will extend the specified super class and implement
+ * specified interfaces.
+ *
+ * @return array where elements with even indexes specifies class name
+ * and the following odd index gives class file body as byte[]
+ * array. The initial element of the array always holds
+ * mainClassName and array[1] holds its byte code.
+ */
+ public Object[] compileToClassFiles(String source,
+ String sourceLocation,
+ int lineno,
+ String mainClassName)
+ {
+ return null;
+ }
+ }
\ No newline at end of file
diff --git a/java/ql/test/stubs/scriptengine/javax/script/Bindings.java b/java/ql/test/stubs/scriptengine/javax/script/Bindings.java
new file mode 100644
index 00000000000..a8eeeb6fe5e
--- /dev/null
+++ b/java/ql/test/stubs/scriptengine/javax/script/Bindings.java
@@ -0,0 +1,14 @@
+package javax.script;
+import java.util.Map;
+
+public interface Bindings extends Map {
+ public Object put(String name, Object value);
+
+ public void putAll(Map extends String, ? extends Object> toMerge);
+
+ public boolean containsKey(Object key);
+
+ public Object get(Object key);
+
+ public Object remove(Object key);
+}
diff --git a/java/ql/test/stubs/scriptengine/javax/script/Compilable.java b/java/ql/test/stubs/scriptengine/javax/script/Compilable.java
new file mode 100644
index 00000000000..ce6700c5a66
--- /dev/null
+++ b/java/ql/test/stubs/scriptengine/javax/script/Compilable.java
@@ -0,0 +1,9 @@
+package javax.script;
+
+import java.io.Reader;
+
+public interface Compilable {
+ public CompiledScript compile(String script) throws ScriptException;
+
+ public CompiledScript compile(Reader script) throws ScriptException;
+}
diff --git a/java/ql/test/stubs/scriptengine/javax/script/CompiledScript.java b/java/ql/test/stubs/scriptengine/javax/script/CompiledScript.java
new file mode 100644
index 00000000000..2f03d58c9a7
--- /dev/null
+++ b/java/ql/test/stubs/scriptengine/javax/script/CompiledScript.java
@@ -0,0 +1,17 @@
+package javax.script;
+
+public abstract class CompiledScript {
+
+ public abstract Object eval(ScriptContext context) throws ScriptException;
+
+ public Object eval(Bindings bindings) throws ScriptException {
+ return null;
+ }
+
+ public Object eval() throws ScriptException {
+ return null;
+ }
+
+ public abstract ScriptEngine getEngine();
+
+}
\ No newline at end of file
diff --git a/java/ql/test/stubs/scriptengine/javax/script/ScriptEngine.java b/java/ql/test/stubs/scriptengine/javax/script/ScriptEngine.java
index 4dc4f8c3186..35b91119e4f 100644
--- a/java/ql/test/stubs/scriptengine/javax/script/ScriptEngine.java
+++ b/java/ql/test/stubs/scriptengine/javax/script/ScriptEngine.java
@@ -2,5 +2,7 @@ package javax.script;
public interface ScriptEngine {
Object eval(String var1) throws ScriptException;
+
+ public ScriptEngineFactory getFactory();
}
diff --git a/java/ql/test/stubs/scriptengine/javax/script/ScriptEngineFactory.java b/java/ql/test/stubs/scriptengine/javax/script/ScriptEngineFactory.java
index 7441c8a4ade..f802d86f80b 100644
--- a/java/ql/test/stubs/scriptengine/javax/script/ScriptEngineFactory.java
+++ b/java/ql/test/stubs/scriptengine/javax/script/ScriptEngineFactory.java
@@ -1,6 +1,11 @@
package javax.script;
public interface ScriptEngineFactory {
+ public String getEngineName();
+
+ public String getMethodCallSyntax(String obj, String m, String... args);
+
+ public String getProgram(String... statements);
+
ScriptEngine getScriptEngine();
}
-
diff --git a/java/ql/test/stubs/scriptengine/jdk/nashorn/api/scripting/ClassFilter.java b/java/ql/test/stubs/scriptengine/jdk/nashorn/api/scripting/ClassFilter.java
new file mode 100644
index 00000000000..fcc624fc106
--- /dev/null
+++ b/java/ql/test/stubs/scriptengine/jdk/nashorn/api/scripting/ClassFilter.java
@@ -0,0 +1,5 @@
+package jdk.nashorn.api.scripting;
+
+public interface ClassFilter {
+ public boolean exposeToScripts(String className);
+}
diff --git a/java/ql/test/stubs/scriptengine/jdk/nashorn/api/scripting/NashornScriptEngine.java b/java/ql/test/stubs/scriptengine/jdk/nashorn/api/scripting/NashornScriptEngine.java
index 8dc3c1afa10..e89282dfa27 100644
--- a/java/ql/test/stubs/scriptengine/jdk/nashorn/api/scripting/NashornScriptEngine.java
+++ b/java/ql/test/stubs/scriptengine/jdk/nashorn/api/scripting/NashornScriptEngine.java
@@ -1,10 +1,31 @@
package jdk.nashorn.api.scripting;
-import javax.script.*;
+import java.io.Reader;
-public final class NashornScriptEngine extends AbstractScriptEngine {
+import javax.script.AbstractScriptEngine;
+import javax.script.Compilable;
+import javax.script.CompiledScript;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptException;
+
+public final class NashornScriptEngine extends AbstractScriptEngine implements Compilable {
public Object eval(String var1) throws ScriptException {
return null;
}
-}
+ @Override
+ public ScriptEngineFactory getFactory() {
+ return null;
+ }
+
+ @Override
+ public CompiledScript compile(final Reader reader) throws ScriptException {
+ return null;
+ }
+
+ @Override
+ public CompiledScript compile(final String str) throws ScriptException {
+ return null;
+ }
+}
diff --git a/java/ql/test/stubs/scriptengine/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java b/java/ql/test/stubs/scriptengine/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java
index 763e098ddbe..177bf463eb3 100644
--- a/java/ql/test/stubs/scriptengine/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java
+++ b/java/ql/test/stubs/scriptengine/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java
@@ -3,20 +3,48 @@ package jdk.nashorn.api.scripting;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
-
public final class NashornScriptEngineFactory implements ScriptEngineFactory {
public NashornScriptEngineFactory() {
}
+ @Override
+ public String getEngineName() {
+ return null;
+ }
+ @Override
+ public String getMethodCallSyntax(final String obj, final String method, final String... args) {
+ return null;
+ }
+
+ @Override
+ public String getProgram(final String... statements) {
+ return null;
+ }
+
+ @Override
public ScriptEngine getScriptEngine() {
return null;
}
+ public ScriptEngine getScriptEngine(final ClassLoader appLoader) {
+ return null;
+ }
- public ScriptEngine getScriptEngine(String... args) {
+ public ScriptEngine getScriptEngine(final ClassFilter classFilter) {
+ return null;
+ }
+
+ public ScriptEngine getScriptEngine(final String... args) {
+ return null;
+ }
+
+ public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader) {
+ return null;
+ }
+
+ public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) {
return null;
}
}
-