Files
codeql/java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll

104 lines
3.6 KiB
Plaintext

/** Provides dataflow configurations for tainted path queries. */
import java
import semmle.code.java.frameworks.Networking
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.dataflow.ExternalFlow
import semmle.code.java.security.PathSanitizer
private import semmle.code.java.security.Sanitizers
/** A sink for tainted path flow configurations. */
abstract class TaintedPathSink extends DataFlow::Node { }
private class DefaultTaintedPathSink extends TaintedPathSink {
DefaultTaintedPathSink() { sinkNode(this, "path-injection") }
}
/**
* A unit class for adding additional taint steps.
*
* Extend this class to add additional taint steps that should apply to tainted path flow configurations.
*/
class TaintedPathAdditionalTaintStep extends Unit {
abstract predicate step(DataFlow::Node n1, DataFlow::Node n2);
}
private class DefaultTaintedPathAdditionalTaintStep extends TaintedPathAdditionalTaintStep {
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
exists(Argument a |
a = n1.asExpr() and
a.getCall() = n2.asExpr() and
a = any(TaintPreservingUriCtorParam tpp).getAnArgument()
)
}
}
private class TaintPreservingUriCtorParam extends Parameter {
TaintPreservingUriCtorParam() {
exists(Constructor ctor, int idx, int nParams |
ctor.getDeclaringType() instanceof TypeUri and
this = ctor.getParameter(idx) and
nParams = ctor.getNumberOfParameters()
|
// URI(String scheme, String ssp, String fragment)
idx = 1 and nParams = 3
or
// URI(String scheme, String host, String path, String fragment)
idx = [1, 2] and nParams = 4
or
// URI(String scheme, String authority, String path, String query, String fragment)
idx = 2 and nParams = 5
or
// URI(String scheme, String userInfo, String host, int port, String path, String query, String fragment)
idx = 4 and nParams = 7
)
}
}
/**
* A taint-tracking configuration for tracking flow from remote sources to the creation of a path.
*/
module TaintedPathConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof ThreatModelFlowSource }
predicate isSink(DataFlow::Node sink) { sink instanceof TaintedPathSink }
predicate isBarrier(DataFlow::Node sanitizer) {
sanitizer instanceof SimpleTypeSanitizer or
sanitizer instanceof PathInjectionSanitizer
}
predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
any(TaintedPathAdditionalTaintStep s).step(n1, n2)
}
}
/** Tracks flow from remote sources to the creation of a path. */
module TaintedPathFlow = TaintTracking::Global<TaintedPathConfig>;
/**
* A taint-tracking configuration for tracking flow from local user input to the creation of a path.
*/
deprecated module TaintedPathLocalConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
predicate isSink(DataFlow::Node sink) { sink instanceof TaintedPathSink }
predicate isBarrier(DataFlow::Node sanitizer) {
sanitizer instanceof SimpleTypeSanitizer or
sanitizer instanceof PathInjectionSanitizer
}
predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
any(TaintedPathAdditionalTaintStep s).step(n1, n2)
}
}
/**
* DEPRECATED: Use `TaintedPathFlow` instead and configure threat model sources to include `local`.
*
* Tracks flow from local user input to the creation of a path.
*/
deprecated module TaintedPathLocalFlow = TaintTracking::Global<TaintedPathLocalConfig>;