mirror of
https://github.com/github/codeql.git
synced 2026-05-22 15:17:09 +02:00
https://github.com/d10c/codeql/blob/d10c/diff-informed-phase-3/java/ql/src/Security/CWE/CWE-807/ConditionalBypass.ql#L26
65 lines
2.1 KiB
Plaintext
65 lines
2.1 KiB
Plaintext
/**
|
|
* Provides classes to be used in queries related to vulnerabilities
|
|
* about unstrusted input being used in security decisions.
|
|
*/
|
|
|
|
import java
|
|
import semmle.code.java.dataflow.FlowSources
|
|
import semmle.code.java.security.SensitiveActions
|
|
import semmle.code.java.controlflow.Guards
|
|
|
|
/**
|
|
* Holds if `ma` is controlled by the condition expression `e`.
|
|
*/
|
|
predicate conditionControlsMethod(MethodCall ma, Expr e) {
|
|
exists(ConditionBlock cb, SensitiveExecutionMethod m, boolean cond |
|
|
ma.getMethod() = m and
|
|
cb.controls(ma.getBasicBlock(), cond) and
|
|
not cb.controls(any(SensitiveExecutionMethod sem).getAReference().getBasicBlock(),
|
|
cond.booleanNot()) and
|
|
not cb.controls(any(ThrowStmt t).getBasicBlock(), cond.booleanNot()) and
|
|
not cb.controls(any(ReturnStmt r).getBasicBlock(), cond.booleanNot()) and
|
|
e = cb.getCondition()
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Holds if `node1` to `node2` is a dataflow step through the
|
|
* `endsWith` method of the `java.lang.String` class.
|
|
*/
|
|
private predicate endsWithStep(DataFlow::Node node1, DataFlow::Node node2) {
|
|
exists(MethodCall ma |
|
|
ma.getMethod().getDeclaringType() instanceof TypeString and
|
|
ma.getMethod().getName() = "endsWith" and
|
|
ma.getQualifier() = node1.asExpr() and
|
|
ma = node2.asExpr()
|
|
)
|
|
}
|
|
|
|
/**
|
|
* A taint tracking configuration for untrusted data flowing to sensitive conditions.
|
|
*/
|
|
module ConditionalBypassFlowConfig implements DataFlow::ConfigSig {
|
|
predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource }
|
|
|
|
predicate isSink(DataFlow::Node sink) { conditionControlsMethod(_, sink.asExpr()) }
|
|
|
|
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
|
endsWithStep(node1, node2)
|
|
}
|
|
|
|
predicate observeDiffInformedIncrementalMode() { any() }
|
|
|
|
Location getASelectedSinkLocation(DataFlow::Node sink) {
|
|
exists(MethodCall m, Expr e | result = [m, e].getLocation() |
|
|
conditionControlsMethod(m, e) and
|
|
sink.asExpr() = e
|
|
)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Taint tracking flow for untrusted data flowing to sensitive conditions.
|
|
*/
|
|
module ConditionalBypassFlow = TaintTracking::Global<ConditionalBypassFlowConfig>;
|