Moved from experimental to standard

This commit is contained in:
Tony Torralba
2021-05-11 15:42:13 +02:00
parent 53da3b661a
commit fc03b92e11
17 changed files with 4 additions and 3 deletions

View File

@@ -0,0 +1,17 @@
import ognl.Ognl;
import ognl.OgnlException;
public void evaluate(HttpServletRequest request, Object root) throws OgnlException {
String expression = request.getParameter("expression");
// BAD: User provided expression is evaluated
Ognl.getValue(expression, root);
// GOOD: The name is validated and expression is evaluated in sandbox
System.setProperty("ognl.security.manager", ""); // Or add -Dognl.security.manager to JVM args
if (isValid(expression)) {
Ognl.getValue(expression, root);
} else {
// Reject the request
}
}

View File

@@ -0,0 +1,33 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Object-Graph Navigation Language (OGNL) is an open-source Expression Language (EL) for Java. Due
to its ability to create or change executable code, OGNL is capable of introducing critical
security flaws to any application that uses it. Evaluation of unvalidated expressions can let
attacker to modify Java objects' properties or execute arbitrary code.</p>
</overview>
<recommendation>
<p>The general recommendation is to not evaluate untrusted ONGL expressions. If user provided OGNL
expressions must be evaluated, do this in sandbox (add `-Dognl.security.manager` to JVM arguments)
and validate the expressions before evaluation.</p>
</recommendation>
<example>
<p>In the following examples, the code accepts an OGNL expression from the user and evaluates it.
</p>
<p>In the first example, the user provided OGNL expression is parsed and evaluated.</p>
<p>The second example validates the expression and evaluates it inside the sandbox.</p>
<sample src="OgnlInjection.java" />
</example>
<references>
<li><a href="https://github.com/jkuhnert/ognl/">OGNL library</a>.</li>
<li>Struts security: <a href="https://struts.apache.org/security/#proactively-protect-from-ognl-expression-injections-attacks-if-easily-applicable">Proactively protect from OGNL Expression Injections attacks</a>.</li>
</references>
</qhelp>

View File

@@ -0,0 +1,40 @@
/**
* @name OGNL Expression Language statement with user-controlled input
* @description Evaluation of OGNL Expression Language statement with user-controlled input can
* lead to execution of arbitrary code.
* @kind path-problem
* @problem.severity error
* @precision high
* @id java/ognl-injection
* @tags security
* external/cwe/cwe-917
*/
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.OgnlInjection
import DataFlow::PathGraph
/**
* A taint-tracking configuration for unvalidated user input that is used in OGNL EL evaluation.
*/
class OgnlInjectionFlowConfig extends TaintTracking::Configuration {
OgnlInjectionFlowConfig() { this = "OgnlInjectionFlowConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof OgnlInjectionSink }
override predicate isSanitizer(DataFlow::Node node) {
node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType
}
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
any(OgnlInjectionAdditionalTaintStep c).step(node1, node2)
}
}
from DataFlow::PathNode source, DataFlow::PathNode sink, OgnlInjectionFlowConfig conf
where conf.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "OGNL expression might include input from $@.",
source.getNode(), "this user input"