Initial commit

This commit is contained in:
SpaceWhite
2020-02-15 16:27:03 +09:00
parent 931c0e982e
commit a29ccd674f
2 changed files with 78 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p> The ScriptEngine api is available since the release of Java 6.
It allows application to interact with script written in language such as JavaScript.</p>
</overview>
<recommendation>
Use "Cloudbees Rhino Sandbox" or sandboxing with SecurityManager or use <a href="https://www.graalvm.org/">graalvm</a> instead
</recommendation>
<example>
The following code could executes random JavaScript code
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension("js");
Object result = scriptEngine.eval(code);
</example>
<references>
<li>
CERT coding standard: <a href="https://wiki.sei.cmu.edu/confluence/display/java/IDS52-J.+Prevent+code+injection">ScriptEngine code injection</a>
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,51 @@
/**
* @name Script engine eval
* @description Malicious javascript code could caused arbitrary command execution on OS level
* @kind path-problem
* @problem.severity error
* @precision high
* @id java/unsafe-eval
* @tags security
* external/cwe/cwe-094
*/
import java
import semmle.code.java.dataflow.FlowSources
import DataFlow::PathGraph
class ScriptEngineMethod extends Method {
ScriptEngineMethod() {
this.getDeclaringType().hasQualifiedName("javax.script", "ScriptEngine") and
this.hasName("eval")
}
}
predicate scriptEngine(MethodAccess ma, Expr sink) {
exists(Method m | m = ma.getMethod() |
m instanceof ScriptEngineMethod and
sink = ma.getArgument(0)
)
}
class ScriptEngineSink extends DataFlow::ExprNode {
ScriptEngineSink() { scriptEngine(_, this.getExpr()) }
MethodAccess getMethodAccess() { scriptEngine(result, this.getExpr()) }
}
class ScriptEngineConfiguration extends TaintTracking::Configuration {
ScriptEngineConfiguration() { this = "ScriptEngineConfiguration" }
override predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource
or
source instanceof LocalUserInput
}
override predicate isSink(DataFlow::Node sink) { sink instanceof ScriptEngineSink }
}
from DataFlow::PathNode source, DataFlow::PathNode sink, ScriptEngineConfiguration conf
where conf.hasFlowPath(source, sink)
select sink.getNode().(ScriptEngineSink).getMethodAccess(), source, sink, "Script engine eval $@.",
source.getNode(), "user input"