Refactor Injection queries

This commit is contained in:
Ed Minnix
2023-04-12 10:23:12 -04:00
parent 7002ed5303
commit d254d91f57
10 changed files with 73 additions and 63 deletions

View File

@@ -14,16 +14,15 @@
import java
import BeanShellInjection
import semmle.code.java.dataflow.FlowSources
import DataFlow::PathGraph
import semmle.code.java.dataflow.TaintTracking
import BeanShellInjectionFlow::PathGraph
class BeanShellInjectionConfig extends TaintTracking::Configuration {
BeanShellInjectionConfig() { this = "BeanShellInjectionConfig" }
module BeanShellInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
predicate isSink(DataFlow::Node sink) { sink instanceof BeanShellInjectionSink }
override predicate isSink(DataFlow::Node sink) { sink instanceof BeanShellInjectionSink }
override predicate isAdditionalTaintStep(DataFlow::Node prod, DataFlow::Node succ) {
predicate isAdditionalFlowStep(DataFlow::Node prod, DataFlow::Node succ) {
exists(ClassInstanceExpr cie |
cie.getConstructedType()
.hasQualifiedName("org.springframework.scripting.support", "StaticScriptSource") and
@@ -42,7 +41,9 @@ class BeanShellInjectionConfig extends TaintTracking::Configuration {
}
}
from DataFlow::PathNode source, DataFlow::PathNode sink, BeanShellInjectionConfig conf
where conf.hasFlowPath(source, sink)
module BeanShellInjectionFlow = TaintTracking::Global<BeanShellInjectionConfig>;
from BeanShellInjectionFlow::PathNode source, BeanShellInjectionFlow::PathNode sink
where BeanShellInjectionFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "BeanShell injection from $@.", source.getNode(),
"this user input"

View File

@@ -13,9 +13,9 @@
import java
import InsecureDexLoading
import DataFlow::PathGraph
import InsecureDexFlow::PathGraph
from DataFlow::PathNode source, DataFlow::PathNode sink, InsecureDexConfiguration conf
where conf.hasFlowPath(source, sink)
from InsecureDexFlow::PathNode source, InsecureDexFlow::PathNode sink
where InsecureDexFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "Potential arbitrary code execution due to $@.",
source.getNode(), "a value loaded from a world-writable source."

View File

@@ -1,22 +1,21 @@
import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources
/**
* A taint-tracking configuration detecting unsafe use of a
* `DexClassLoader` by an Android app.
*/
class InsecureDexConfiguration extends TaintTracking::Configuration {
InsecureDexConfiguration() { this = "Insecure Dex File Load" }
module InsecureDexConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof InsecureDexSource }
override predicate isSource(DataFlow::Node source) { source instanceof InsecureDexSource }
predicate isSink(DataFlow::Node sink) { sink instanceof InsecureDexSink }
override predicate isSink(DataFlow::Node sink) { sink instanceof InsecureDexSink }
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
flowStep(pred, succ)
}
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { flowStep(pred, succ) }
}
module InsecureDexFlow = TaintTracking::Global<InsecureDexConfig>;
/** A data flow source for insecure Dex class loading vulnerabilities. */
abstract class InsecureDexSource extends DataFlow::Node { }

View File

@@ -14,16 +14,15 @@
import java
import JShellInjection
import semmle.code.java.dataflow.FlowSources
import DataFlow::PathGraph
import semmle.code.java.dataflow.TaintTracking
import JShellInjectionFlow::PathGraph
class JShellInjectionConfiguration extends TaintTracking::Configuration {
JShellInjectionConfiguration() { this = "JShellInjectionConfiguration" }
module JShellInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
predicate isSink(DataFlow::Node sink) { sink instanceof JShellInjectionSink }
override predicate isSink(DataFlow::Node sink) { sink instanceof JShellInjectionSink }
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
exists(SourceCodeAnalysisAnalyzeCompletionCall scaacc |
scaacc.getArgument(0) = pred.asExpr() and scaacc = succ.asExpr()
)
@@ -34,7 +33,9 @@ class JShellInjectionConfiguration extends TaintTracking::Configuration {
}
}
from DataFlow::PathNode source, DataFlow::PathNode sink, JShellInjectionConfiguration conf
where conf.hasFlowPath(source, sink)
module JShellInjectionFlow = TaintTracking::Global<JShellInjectionConfig>;
from JShellInjectionFlow::PathNode source, JShellInjectionFlow::PathNode sink
where JShellInjectionFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "JShell injection from $@.", source.getNode(),
"this user input"

View File

@@ -13,9 +13,9 @@
import java
import JakartaExpressionInjectionLib
import DataFlow::PathGraph
import JakartaExpressionInjectionFlow::PathGraph
from DataFlow::PathNode source, DataFlow::PathNode sink, JakartaExpressionInjectionConfig conf
where conf.hasFlowPath(source, sink)
from JakartaExpressionInjectionFlow::PathNode source, JakartaExpressionInjectionFlow::PathNode sink
where JakartaExpressionInjectionFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "Jakarta Expression Language injection from $@.",
source.getNode(), "this user input"

View File

@@ -7,19 +7,22 @@ import semmle.code.java.dataflow.TaintTracking
* A taint-tracking configuration for unsafe user input
* that is used to construct and evaluate an expression.
*/
class JakartaExpressionInjectionConfig extends TaintTracking::Configuration {
JakartaExpressionInjectionConfig() { this = "JakartaExpressionInjectionConfig" }
module JakartaExpressionInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
predicate isSink(DataFlow::Node sink) { sink instanceof ExpressionEvaluationSink }
override predicate isSink(DataFlow::Node sink) { sink instanceof ExpressionEvaluationSink }
override predicate isAdditionalTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) {
predicate isAdditionalFlowStep(DataFlow::Node fromNode, DataFlow::Node toNode) {
any(TaintPropagatingCall c).taintFlow(fromNode, toNode) or
hasGetterFlow(fromNode, toNode)
}
}
/**
* Taint-tracking flow from remote sources, through an expression, to its eventual evaluation.
*/
module JakartaExpressionInjectionFlow = TaintTracking::Global<JakartaExpressionInjectionConfig>;
/**
* A sink for Expresssion Language injection vulnerabilities,
* i.e. method calls that run evaluation of an expression.

View File

@@ -14,8 +14,9 @@
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.frameworks.spring.SpringController
import DataFlow::PathGraph
import CodeInjectionFlow::PathGraph
/** The class `org.python.util.PythonInterpreter`. */
class PythonInterpreter extends RefType {
@@ -101,15 +102,19 @@ class CodeInjectionSink extends DataFlow::ExprNode {
* A taint configuration for tracking flow from `RemoteFlowSource` to a Jython method call
* `CodeInjectionSink` that executes injected code.
*/
class CodeInjectionConfiguration extends TaintTracking::Configuration {
CodeInjectionConfiguration() { this = "CodeInjectionConfiguration" }
module CodeInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof CodeInjectionSink }
predicate isSink(DataFlow::Node sink) { sink instanceof CodeInjectionSink }
}
from DataFlow::PathNode source, DataFlow::PathNode sink, CodeInjectionConfiguration conf
where conf.hasFlowPath(source, sink)
/**
* Taint tracking flow from `RemoteFlowSource` to a Jython method call
* `CodeInjectionSink` that executes injected code.
*/
module CodeInjectionFlow = TaintTracking::Global<CodeInjectionConfig>;
from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink
where CodeInjectionFlow::flowPath(source, sink)
select sink.getNode().(CodeInjectionSink).getMethodAccess(), source, sink, "Jython evaluate $@.",
source.getNode(), "user input"

View File

@@ -12,8 +12,9 @@
*/
import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources
import DataFlow::PathGraph
import ScriptInjectionFlow::PathGraph
/** A method of ScriptEngine that allows code injection. */
class ScriptEngineMethod extends Method {
@@ -133,15 +134,15 @@ class ScriptInjectionSink extends DataFlow::ExprNode {
* A taint tracking configuration that tracks flow from `RemoteFlowSource` to an argument
* of a method call that executes injected script.
*/
class ScriptInjectionConfiguration extends TaintTracking::Configuration {
ScriptInjectionConfiguration() { this = "ScriptInjectionConfiguration" }
module ScriptInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof ScriptInjectionSink }
predicate isSink(DataFlow::Node sink) { sink instanceof ScriptInjectionSink }
}
from DataFlow::PathNode source, DataFlow::PathNode sink, ScriptInjectionConfiguration conf
where conf.hasFlowPath(source, sink)
module ScriptInjectionFlow = TaintTracking::Global<ScriptInjectionConfig>;
from ScriptInjectionFlow::PathNode source, ScriptInjectionFlow::PathNode sink
where ScriptInjectionFlow::flowPath(source, sink)
select sink.getNode().(ScriptInjectionSink).getMethodAccess(), source, sink,
"Java Script Engine evaluate $@.", source.getNode(), "user input"

View File

@@ -12,11 +12,11 @@
import java
import SpringViewManipulationLib
import DataFlow::PathGraph
import SpringViewManipulationFlow::PathGraph
from DataFlow::PathNode source, DataFlow::PathNode sink, SpringViewManipulationConfig conf
from SpringViewManipulationFlow::PathNode source, SpringViewManipulationFlow::PathNode sink
where
thymeleafIsUsed() and
conf.hasFlowPath(source, sink)
SpringViewManipulationFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "Potential Spring Expression Language injection from $@.",
source.getNode(), "this user input"

View File

@@ -40,18 +40,16 @@ class PortletRenderRequestMethod extends Method {
* A taint-tracking configuration for unsafe user input
* that can lead to Spring View Manipulation vulnerabilities.
*/
class SpringViewManipulationConfig extends TaintTracking::Configuration {
SpringViewManipulationConfig() { this = "Spring View Manipulation Config" }
override predicate isSource(DataFlow::Node source) {
module SpringViewManipulationConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource or
source instanceof WebRequestSource or
source.asExpr().(MethodAccess).getMethod() instanceof PortletRenderRequestMethod
}
override predicate isSink(DataFlow::Node sink) { sink instanceof SpringViewManipulationSink }
predicate isSink(DataFlow::Node sink) { sink instanceof SpringViewManipulationSink }
override predicate isSanitizer(DataFlow::Node node) {
predicate isBarrier(DataFlow::Node node) {
// Block flows like
// ```
// a = "redirect:" + taint`
@@ -88,6 +86,8 @@ class SpringViewManipulationConfig extends TaintTracking::Configuration {
}
}
module SpringViewManipulationFlow = TaintTracking::Global<SpringViewManipulationConfig>;
private Call getAStringCombiningCall() {
exists(StringCombiningMethod m | result = m.getAReference())
}