Merge pull request #20077 from d10c/d10c/diff-informed-phase-3-java

Java: Diff-informed queries: phase 3 (non-trivial locations)
This commit is contained in:
Nora Dimitrijević
2025-07-21 11:23:12 +02:00
committed by GitHub
53 changed files with 10491 additions and 2071 deletions

View File

@@ -149,6 +149,8 @@ module SensitiveCommunicationConfig implements DataFlow::ConfigSig {
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
isSink(node) and exists(c)
}
predicate observeDiffInformedIncrementalMode() { any() }
}
/**

View File

@@ -13,6 +13,14 @@ module ArithmeticOverflowConfig implements DataFlow::ConfigSig {
predicate isBarrier(DataFlow::Node n) { overflowBarrier(n) }
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
predicate observeDiffInformedIncrementalMode() {
any() // merged with ArithmeticUnderflow in ArithmeticTainted.ql
}
Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(ArithExpr exp | result = exp.getLocation() | overflowSink(exp, sink.asExpr()))
}
}
/**
@@ -29,6 +37,14 @@ module ArithmeticUnderflowConfig implements DataFlow::ConfigSig {
predicate isBarrier(DataFlow::Node n) { underflowBarrier(n) }
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
predicate observeDiffInformedIncrementalMode() {
any() // merged with ArithmeticOverflow in ArithmeticTainted.ql
}
Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(ArithExpr exp | result = exp.getLocation() | underflowSink(exp, sink.asExpr()))
}
}
/**

View File

@@ -19,6 +19,14 @@ module ArithmeticUncontrolledOverflowConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { overflowSink(_, sink.asExpr()) }
predicate isBarrier(DataFlow::Node n) { overflowBarrier(n) }
predicate observeDiffInformedIncrementalMode() {
any() // merged with ArithmeticUncontrolledUnderflow in ArithmeticUncontrolled.ql
}
Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(ArithExpr exp | result = exp.getLocation() | overflowSink(exp, sink.asExpr()))
}
}
/** Taint-tracking flow to reason about overflow from arithmetic with uncontrolled values. */
@@ -32,6 +40,14 @@ module ArithmeticUncontrolledUnderflowConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { underflowSink(_, sink.asExpr()) }
predicate isBarrier(DataFlow::Node n) { underflowBarrier(n) }
predicate observeDiffInformedIncrementalMode() {
any() // merged with ArithmeticUncontrolledOverflow in ArithmeticUncontrolled.ql
}
Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(ArithExpr exp | result = exp.getLocation() | underflowSink(exp, sink.asExpr()))
}
}
/** Taint-tracking flow to reason about underflow from arithmetic with uncontrolled values. */

View File

@@ -47,6 +47,15 @@ module ConditionalBypassFlowConfig implements DataFlow::ConfigSig {
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
)
}
}
/**

View File

@@ -101,6 +101,10 @@ module UntrustedDataToExternalApiConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource }
predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode }
predicate observeDiffInformedIncrementalMode() {
any() // Simple use in UntrustedDataToExternalAPI.ql; also used through ExternalApiUsedWithUntrustedData in ExternalAPIsUsedWithUntrustedData.ql
}
}
/**

View File

@@ -17,6 +17,15 @@ module BoundedFlowSourceConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) {
any(CheckableArrayAccess caa).canThrowOutOfBoundsDueToEmptyArray(sink.asExpr(), _)
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(ArrayCreationExpr arrayCreation, CheckableArrayAccess arrayAccess |
result = [arrayCreation, arrayAccess.getIndexExpr()].getLocation() and
arrayAccess.canThrowOutOfBoundsDueToEmptyArray(sink.asExpr(), arrayCreation)
)
}
}
/**

View File

@@ -14,6 +14,15 @@ module ImproperValidationOfArrayConstructionConfig implements DataFlow::ConfigSi
predicate isSink(DataFlow::Node sink) {
any(CheckableArrayAccess caa).canThrowOutOfBoundsDueToEmptyArray(sink.asExpr(), _)
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(ArrayCreationExpr arrayCreation, CheckableArrayAccess arrayAccess |
result = [arrayCreation, arrayAccess.getIndexExpr()].getLocation() and
arrayAccess.canThrowOutOfBoundsDueToEmptyArray(sink.asExpr(), arrayCreation)
)
}
}
/**

View File

@@ -14,6 +14,8 @@ module BoundedFlowSourceConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) {
exists(CheckableArrayAccess arrayAccess | arrayAccess.canThrowOutOfBounds(sink.asExpr()))
}
predicate observeDiffInformedIncrementalMode() { any() }
}
/**

View File

@@ -18,6 +18,8 @@ module ImproperValidationOfArrayIndexConfig implements DataFlow::ConfigSig {
predicate isBarrier(DataFlow::Node node) { node.getType() instanceof BooleanType }
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
predicate observeDiffInformedIncrementalMode() { any() }
}
/**

View File

@@ -35,6 +35,10 @@ module SecureCookieConfig implements DataFlow::ConfigSig {
sink.asExpr() =
any(MethodCall add | add.getMethod() instanceof ResponseAddCookieMethod).getArgument(0)
}
predicate observeDiffInformedIncrementalMode() {
none() // only used negatively in InsecureCookie.ql
}
}
/** Data flow to reason about the failure to use secure cookies. */

View File

@@ -40,6 +40,10 @@ private module BasicAuthConfig implements DataFlow::ConfigSig {
}
predicate isSink(DataFlow::Node sink) { sink instanceof InsecureLdapUrlSink }
predicate observeDiffInformedIncrementalMode() {
none() // used as secondary flow to InsecureLdapUrlFlow in InsecureLdapAuth.ql
}
}
module BasicAuthFlow = DataFlow::Global<BasicAuthConfig>;
@@ -56,6 +60,10 @@ private module RequiresSslConfig implements DataFlow::ConfigSig {
}
predicate isSink(DataFlow::Node sink) { sink instanceof InsecureLdapUrlSink }
predicate observeDiffInformedIncrementalMode() {
none() // only used negatively in InsecureLdapAuth.ql
}
}
module RequiresSslFlow = DataFlow::Global<RequiresSslConfig>;

View File

@@ -19,6 +19,10 @@ module LogInjectionConfig implements DataFlow::ConfigSig {
}
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
predicate observeDiffInformedIncrementalMode() {
none() // straightforward case; but the large test source is causing OOMs under `--check-diff-informed`.
}
}
/**

View File

@@ -77,6 +77,12 @@ module InsecureCryptoConfig implements DataFlow::ConfigSig {
objectToString(n.asExpr()) or
n.getType().getErasure() instanceof TypeObject
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(CryptoAlgoSpec c | result = c.getLocation() | sink.asExpr() = c.getAlgoSpec())
}
}
/**

View File

@@ -53,6 +53,8 @@ module SensitiveLoggerConfig implements DataFlow::ConfigSig {
}
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
predicate observeDiffInformedIncrementalMode() { any() }
}
module SensitiveLoggerFlow = TaintTracking::Global<SensitiveLoggerConfig>;

View File

@@ -24,6 +24,15 @@ module UncontrolledStringBuilderSourceFlowConfig implements DataFlow::ConfigSig
predicate isSink(DataFlow::Node sink) { sink instanceof QueryInjectionSink }
predicate isBarrier(DataFlow::Node node) { node instanceof SimpleTypeSanitizer }
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node source) {
exists(Expr uncontrolled, StringBuilderVar sbv | result = uncontrolled.getLocation() |
uncontrolledStringBuilderQuery(sbv, uncontrolled) and
source = DataFlow::exprNode(sbv.getToStringCall())
)
}
}
/**

View File

@@ -38,6 +38,10 @@ module ExecTaintedEnvironmentConfig implements DataFlow::ConfigSig {
ProcessBuilderEnvironmentFlow::flowToExpr(mm.getQualifier())
)
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node source) { none() }
}
/**

View File

@@ -145,6 +145,10 @@ module TempDirSystemGetPropertyToCreateConfig implements DataFlow::ConfigSig {
or
sanitizer instanceof WindowsOsSanitizer
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSinkLocation(DataFlow::Node sink) { none() }
}
/**

View File

@@ -62,6 +62,8 @@ module TrustBoundaryConfig implements DataFlow::ConfigSig {
}
predicate isSink(DataFlow::Node sink) { sink instanceof TrustBoundaryViolationSink }
predicate observeDiffInformedIncrementalMode() { any() }
}
/**

View File

@@ -14,6 +14,10 @@ module SslEndpointIdentificationFlowConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { sink instanceof SslConnectionCreation }
predicate isBarrier(DataFlow::Node sanitizer) { sanitizer instanceof SslUnsafeCertTrustSanitizer }
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node source) { none() }
}
/**