mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Initial commit
This commit is contained in:
27
java/ql/src/Security/CWE/CWE-094/ScriptEngine.qhelp
Normal file
27
java/ql/src/Security/CWE/CWE-094/ScriptEngine.qhelp
Normal 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>
|
||||
51
java/ql/src/Security/CWE/CWE-094/ScriptEngine.ql
Normal file
51
java/ql/src/Security/CWE/CWE-094/ScriptEngine.ql
Normal 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"
|
||||
Reference in New Issue
Block a user