Merge pull request #18340 from jbj/diff-informed-getASelectedLocation

Java: make more queries diff-informed with getASelectedLocation
This commit is contained in:
Jonas Jensen
2025-01-22 14:25:33 +01:00
committed by GitHub
13 changed files with 167 additions and 5 deletions

View File

@@ -31,6 +31,12 @@ module InsecureCryptoConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node n) { exists(CryptoAlgoSpec c | n.asExpr() = c.getAlgoSpec()) }
predicate isBarrier(DataFlow::Node node) { node instanceof SimpleTypeSanitizer }
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(CryptoAlgoSpec c | sink.asExpr() = c.getAlgoSpec() | result = c.getLocation())
}
}
/**

View File

@@ -58,6 +58,13 @@ module InputToArgumentToExecFlowConfig implements DataFlow::ConfigSig {
predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
any(CommandInjectionAdditionalTaintStep s).step(n1, n2)
}
// It's valid to use diff-informed data flow for this configuration because
// the location of the selected element in the query is contained inside the
// location of the sink. The query, as a predicate, is used negated in
// another query, but that's only to prevent overlapping results between two
// queries.
predicate observeDiffInformedIncrementalMode() { any() }
}
/**

View File

@@ -25,6 +25,25 @@ private module VerifiedIntentConfig implements DataFlow::ConfigSig {
sink.asExpr() = ma.getQualifier()
)
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node src) {
exists(AndroidReceiverXmlElement rec, OnReceiveMethod orm, SystemActionName sa |
src.asParameter() = orm.getIntentParameter() and
anySystemReceiver(rec, orm, sa)
|
result = rec.getLocation()
or
result = orm.getLocation()
or
result = sa.getLocation()
)
}
// All sinks are set to have no locations because sinks aren't selected in
// the query. This effectively means that we're filtering on sources only.
Location getASelectedSinkLocation(DataFlow::Node sink) { none() }
}
private module VerifiedIntentFlow = DataFlow::Global<VerifiedIntentConfig>;
@@ -67,9 +86,8 @@ class SystemActionName extends AndroidActionXmlElement {
string getSystemActionName() { result = name }
}
/** Holds if the XML element `rec` declares a receiver `orm` to receive the system action named `sa` that doesn't verify intents it receives. */
predicate unverifiedSystemReceiver(
AndroidReceiverXmlElement rec, UnverifiedOnReceiveMethod orm, SystemActionName sa
private predicate anySystemReceiver(
AndroidReceiverXmlElement rec, OnReceiveMethod orm, SystemActionName sa
) {
exists(Class ormty |
ormty = orm.getDeclaringType() and
@@ -77,3 +95,11 @@ predicate unverifiedSystemReceiver(
rec.getAnIntentFilterElement().getAnActionElement() = sa
)
}
/** Holds if the XML element `rec` declares a receiver `orm` to receive the system action named `sa` that doesn't verify intents it receives. */
predicate unverifiedSystemReceiver(
AndroidReceiverXmlElement rec, UnverifiedOnReceiveMethod orm, SystemActionName sa
) {
// The type of `orm` is different in these two predicates
anySystemReceiver(rec, orm, sa)
}

View File

@@ -18,6 +18,17 @@ module InsecureTrustManagerConfig implements DataFlow::ConfigSig {
node.getType() instanceof Array and
c instanceof DataFlow::ArrayContent
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node source) {
isSource(source) and
(
result = source.getLocation()
or
result = source.asExpr().(ClassInstanceExpr).getConstructedType().getLocation()
)
}
}
module InsecureTrustManagerFlow = DataFlow::Global<InsecureTrustManagerConfig>;

View File

@@ -37,6 +37,18 @@ private module PredictableSeedFlowConfig implements DataFlow::ConfigSig {
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
predictableCalcStep(node1.asExpr(), node2.asExpr())
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
// This predicate matches `PredictableSeed.ql`, which is the only place
// where `PredictableSeedFlowConfig` is used.
exists(GetRandomData da, VarRead use |
result = da.getLocation() and
da.getQualifier() = use and
isSeeding(sink.asExpr(), use)
)
}
}
private module PredictableSeedFlow = DataFlow::Global<PredictableSeedFlowConfig>;

View File

@@ -24,6 +24,8 @@ module QueryInjectionFlowConfig implements DataFlow::ConfigSig {
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
any(AdditionalQueryInjectionTaintStep s).step(node1, node2)
}
predicate observeDiffInformedIncrementalMode() { any() }
}
/** Tracks flow of unvalidated user input that is used in SQL queries. */

View File

@@ -59,6 +59,15 @@ module TaintedPermissionsCheckFlowConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(PermissionsConstruction p).getInput()
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(PermissionsConstruction p |
sink.asExpr() = p.getInput() and
result = p.getLocation()
)
}
}
/** Tracks flow from user input to a permissions check. */

View File

@@ -65,6 +65,17 @@ module TrustAllHostnameVerifierConfig implements DataFlow::ConfigSig {
"|(set)?(accept|trust|ignore|allow)(all|every|any)" +
"|(use|do|enable)insecure|(set|do|use)?no.*(check|validation|verify|verification)|disable).*$")
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node source) {
isSource(source) and
(
result = source.getLocation()
or
result = source.asExpr().(ClassInstanceExpr).getConstructedType().getLocation()
)
}
}
/** Data flow to model the flow of a `TrustAllHostnameVerifier` to a `set(Default)HostnameVerifier` call. */

View File

@@ -47,6 +47,18 @@ module PolynomialRedosConfig implements DataFlow::ConfigSig {
node instanceof SimpleTypeSanitizer or
node.asExpr().(MethodCall).getMethod() instanceof LengthRestrictedMethod
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(SuperlinearBackTracking::PolynomialBackTrackingTerm regexp |
regexp.getRootTerm() = sink.(PolynomialRedosSink).getRegExp()
|
result = sink.getLocation()
or
result = regexp.getLocation()
)
}
}
module PolynomialRedosFlow = TaintTracking::Global<PolynomialRedosConfig>;