Python: mass enable diff-informed data flow

This commit is contained in:
Asger F
2025-01-23 10:15:59 +01:00
parent 9319b1848d
commit e4a1847dad
55 changed files with 197 additions and 1 deletions

View File

@@ -171,6 +171,13 @@ private module UntrustedDataToExternalApiConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode }
predicate observeDiffInformedIncrementalMode() {
// TODO(diff-informed): Manually verify if config can be diff-informed.
// ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll:181: Flow call outside 'select' clause
// ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll:184: Flow call outside 'select' clause
none()
}
}
/** Global taint-tracking from `RemoteFlowSource`s to `ExternalApiDataNode`s. */

View File

@@ -110,6 +110,12 @@ module InsecureContextConfiguration implements DataFlow::StateConfigSig {
)
)
}
predicate observeDiffInformedIncrementalMode() {
// TODO(diff-informed): Manually verify if config can be diff-informed.
// ql/src/Security/CWE-327/FluentApiModel.qll:130: Flow call outside 'select' clause
none()
}
}
private module InsecureContextFlow = DataFlow::GlobalWithState<InsecureContextConfiguration>;

View File

@@ -119,6 +119,8 @@ private module HardcodedCredentialsConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof HardcodedValueSource }
predicate isSink(DataFlow::Node sink) { sink instanceof CredentialSink }
predicate observeDiffInformedIncrementalMode() { any() }
}
module HardcodedCredentialsFlow = TaintTracking::Global<HardcodedCredentialsConfig>;

View File

@@ -109,6 +109,8 @@ private module TarSlipImprovConfig implements DataFlow::ConfigSig {
nodeFrom = nodeTo.(API::CallNode).getArg(0) and
nodeFrom = tarfileOpen().getReturn().getAValueReachableFromSource()
}
predicate observeDiffInformedIncrementalMode() { any() }
}
/** Global taint-tracking for detecting more "TarSlip" vulnerabilities. */

View File

@@ -19,6 +19,8 @@ module XsltInjectionConfig implements DataFlow::ConfigSig {
// opted for the more simple approach.
nodeTo = elementTreeConstruction(nodeFrom)
}
predicate observeDiffInformedIncrementalMode() { any() }
}
module XsltInjectionFlow = TaintTracking::Global<XsltInjectionConfig>;

View File

@@ -24,6 +24,8 @@ module Js2PyFlowConfig implements DataFlow::ConfigSig {
API::moduleImport("js2py").getMember(["eval_js", "eval_js6", "EvalJs"]).getACall().getArg(_) =
node
}
predicate observeDiffInformedIncrementalMode() { any() }
}
module Js2PyFlow = TaintTracking::Global<Js2PyFlowConfig>;

View File

@@ -75,6 +75,8 @@ private module UnicodeBypassValidationConfig implements DataFlow::StateConfigSig
) and
state instanceof PostValidation
}
predicate observeDiffInformedIncrementalMode() { any() }
}
/** Global taint-tracking for detecting "Unicode transformation mishandling" vulnerabilities. */

View File

@@ -26,6 +26,12 @@ private module PossibleTimingAttackAgainstHashConfig implements DataFlow::Config
predicate isSource(DataFlow::Node source) { source instanceof ProduceCryptoCall }
predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink }
predicate observeDiffInformedIncrementalMode() {
// TODO(diff-informed): Manually verify if config can be diff-informed.
// ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql:41: Column 5 selects source.getResultType
none()
}
}
module PossibleTimingAttackAgainstHashFlow =

View File

@@ -25,6 +25,12 @@ private module TimingAttackAgainstHashConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof ProduceCryptoCall }
predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink }
predicate observeDiffInformedIncrementalMode() {
// TODO(diff-informed): Manually verify if config can be diff-informed.
// ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql:39: Column 5 selects source.getResultType
none()
}
}
module TimingAttackAgainstHashFlow = TaintTracking::Global<TimingAttackAgainstHashConfig>;

View File

@@ -23,6 +23,8 @@ private module TimingAttackAgainstHeaderValueConfig implements DataFlow::ConfigS
predicate isSource(DataFlow::Node source) { source instanceof ClientSuppliedSecret }
predicate isSink(DataFlow::Node sink) { sink instanceof CompareSink }
predicate observeDiffInformedIncrementalMode() { any() }
}
module TimingAttackAgainstHeaderValueFlow =

View File

@@ -23,6 +23,8 @@ private module PossibleTimingAttackAgainstSensitiveInfoConfig implements DataFlo
predicate isSource(DataFlow::Node source) { source instanceof SecretSource }
predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink }
predicate observeDiffInformedIncrementalMode() { any() }
}
module PossibleTimingAttackAgainstSensitiveInfoFlow =

View File

@@ -24,6 +24,8 @@ private module TimingAttackAgainstSensitiveInfoConfig implements DataFlow::Confi
predicate isSource(DataFlow::Node source) { source instanceof SecretSource }
predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink }
predicate observeDiffInformedIncrementalMode() { any() }
}
module TimingAttackAgainstSensitiveInfoFlow =

View File

@@ -52,6 +52,8 @@ private module WebAppConstantSecretKeyConfig implements DataFlow::StateConfigSig
or
state = Django() and DjangoConstantSecretKeyConfig::isSink(sink)
}
predicate observeDiffInformedIncrementalMode() { any() }
}
module WebAppConstantSecretKeyFlow = TaintTracking::GlobalWithState<WebAppConstantSecretKeyConfig>;

View File

@@ -145,6 +145,8 @@ private module AzureBlobClientConfig implements DataFlow::StateConfigSig {
node = call.getObject()
)
}
predicate observeDiffInformedIncrementalMode() { any() }
}
module AzureBlobClientFlow = DataFlow::GlobalWithState<AzureBlobClientConfig>;

View File

@@ -51,6 +51,8 @@ private module TokenBuiltFromUuidConfig implements DataFlow::ConfigSig {
nodeTo = call
)
}
predicate observeDiffInformedIncrementalMode() { any() }
}
/** Global taint-tracking for detecting "TokenBuiltFromUUID" vulnerabilities. */

View File

@@ -79,6 +79,8 @@ module CorsBypassConfig implements DataFlow::ConfigSig {
c.getReturn().asSource() = node2 and n.asSource() = node1
)
}
predicate observeDiffInformedIncrementalMode() { any() }
}
module CorsFlow = TaintTracking::Global<CorsBypassConfig>;

View File

@@ -45,6 +45,8 @@ private module ClientSuppliedIpUsedInSecurityCheckConfig implements DataFlow::Co
ss = node.asExpr()
)
}
predicate observeDiffInformedIncrementalMode() { any() }
}
/** Global taint-tracking for detecting "client ip used in security check" vulnerabilities. */

View File

@@ -108,6 +108,8 @@ private module UnicodeDoSConfig implements DataFlow::ConfigSig {
.getACall()
.getArg(_)
}
predicate observeDiffInformedIncrementalMode() { any() }
}
module UnicodeDoSFlow = TaintTracking::Global<UnicodeDoSConfig>;

View File

@@ -208,6 +208,8 @@ module UnsafeUnpackConfig implements DataFlow::ConfigSig {
nodeFrom = mcn.getArg(0)
)
}
predicate observeDiffInformedIncrementalMode() { any() }
}
/** Global taint-tracking for detecting "UnsafeUnpacking" vulnerabilities. */

View File

@@ -38,6 +38,12 @@ module SmtpLib {
predicate isSink(DataFlow::Node sink) {
sink = smtpMimeMultipartInstance().getACall().getArgByName("_subparts")
}
predicate observeDiffInformedIncrementalMode() {
// TODO(diff-informed): Manually verify if config can be diff-informed.
// ql/src/experimental/semmle/python/libraries/SmtpLib.qll:91: Flow call outside 'select' clause
none()
}
}
module SmtpMessageFlow = TaintTracking::Global<SmtpMessageConfig>;

View File

@@ -408,6 +408,8 @@ module BombsConfig implements DataFlow::ConfigSig {
isAdditionalTaintStepTextIOWrapper(pred, succ)
)
}
predicate observeDiffInformedIncrementalMode() { any() }
}
module BombsFlow = TaintTracking::Global<BombsConfig>;

View File

@@ -27,6 +27,8 @@ module InsecureRandomness {
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
predicate observeDiffInformedIncrementalMode() { any() }
}
/** Global taint-tracking for detecting "random values that are not cryptographically secure" vulnerabilities. */

View File

@@ -101,6 +101,8 @@ private module LdapInsecureAuthConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) {
exists(LdapBind ldapBind | not ldapBind.useSsl() and sink = ldapBind.getHost())
}
predicate observeDiffInformedIncrementalMode() { any() }
}
/** Global taint-tracking for detecting "LDAP insecure authentications" vulnerabilities. */

View File

@@ -10,6 +10,8 @@ module RemoteCommandExecutionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
predicate isSink(DataFlow::Node sink) { sink = any(RemoteCommandExecution rce).getCommand() }
predicate observeDiffInformedIncrementalMode() { any() }
}
/** Global taint-tracking for detecting "secondary server command injection" vulnerabilities. */

View File

@@ -271,6 +271,12 @@ module UserInputSecretConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof CredentialExpr }
predicate observeDiffInformedIncrementalMode() {
// TODO(diff-informed): Manually verify if config can be diff-informed.
// ql/src/experimental/semmle/python/security/TimingAttack.qll:176: Flow call outside 'select' clause
none()
}
}
module UserInputSecretFlow = TaintTracking::Global<UserInputSecretConfig>;
@@ -288,6 +294,12 @@ module UserInputInComparisonConfig implements DataFlow::ConfigSig {
sink.asExpr() = [left, right]
)
}
predicate observeDiffInformedIncrementalMode() {
// TODO(diff-informed): Manually verify if config can be diff-informed.
// ql/src/experimental/semmle/python/security/TimingAttack.qll:165: Flow call outside 'select' clause
none()
}
}
module UserInputInComparisonFlow = TaintTracking::Global<UserInputInComparisonConfig>;
@@ -304,6 +316,12 @@ private module ExcludeLenFuncConfig implements DataFlow::ConfigSig {
sink.asExpr() = call.getArg(0)
)
}
predicate observeDiffInformedIncrementalMode() {
// TODO(diff-informed): Manually verify if config can be diff-informed.
// ql/src/experimental/semmle/python/security/TimingAttack.qll:347: Flow call outside 'select' clause
none()
}
}
module ExcludeLenFuncFlow = TaintTracking::Global<ExcludeLenFuncConfig>;

View File

@@ -34,6 +34,8 @@ private module ZipSlipConfig implements DataFlow::ConfigSig {
) and
not sink.getScope().getLocation().getFile().inStdlib()
}
predicate observeDiffInformedIncrementalMode() { any() }
}
/** Global taint-tracking for detecting "zip slip" vulnerabilities. */

View File

@@ -34,6 +34,8 @@ private module EmailXssConfig implements DataFlow::ConfigSig {
nodeFrom = htmlContentCall.getArg(0)
)
}
predicate observeDiffInformedIncrementalMode() { any() }
}
/** Global taint-tracking for detecting "Email XSS" vulnerabilities. */

View File

@@ -17,6 +17,8 @@ private module CsvInjectionConfig implements DataFlow::ConfigSig {
node = DataFlow::BarrierGuard<startsWithCheck/3>::getABarrierNode() or
node instanceof ConstCompareBarrier
}
predicate observeDiffInformedIncrementalMode() { any() }
}
private predicate startsWithCheck(DataFlow::GuardNode g, ControlFlowNode node, boolean branch) {

View File

@@ -45,11 +45,15 @@ module ModificationOfParameterWithDefault {
copyTarget(node) and state in [true, false]
}
private predicate copyTarget(DataFlow::Node node) {
private predicate observeDiffInformedIncrementalMode() { any() }
predicate copyTarget(DataFlow::Node node) {
node = API::moduleImport("copy").getMember(["copy", "deepcopy"]).getACall()
or
node.(DataFlow::MethodCallNode).calls(_, "copy")
}
predicate observeDiffInformedIncrementalMode() { any() }
}
/** Global data-flow for detecting modifications of a parameters default value. */