From 0019cb10d834701d552ea8ad4ef155441e9ef247 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 5 Sep 2023 09:47:32 +0200 Subject: [PATCH] Revert "Python: Use new dataflow API" --- .../dataflow/CleartextLoggingQuery.qll | 15 +- .../dataflow/CleartextStorageQuery.qll | 15 +- .../security/dataflow/CodeInjectionQuery.qll | 15 +- .../dataflow/CommandInjectionQuery.qll | 18 +- .../security/dataflow/LdapInjectionQuery.qll | 35 +--- .../security/dataflow/LogInjectionQuery.qll | 17 +- .../dataflow/PamAuthorizationQuery.qll | 29 +-- .../security/dataflow/PathInjectionQuery.qll | 53 +---- .../PolynomialReDoSCustomizations.qll | 1 + .../dataflow/PolynomialReDoSQuery.qll | 15 +- .../security/dataflow/ReflectedXssQuery.qll | 15 +- .../security/dataflow/RegexInjectionQuery.qll | 17 +- .../ServerSideRequestForgeryQuery.qll | 59 +----- .../security/dataflow/SqlInjectionQuery.qll | 15 +- .../dataflow/StackTraceExposureQuery.qll | 24 +-- .../python/security/dataflow/TarSlipQuery.qll | 19 +- .../dataflow/UnsafeDeserializationQuery.qll | 15 +- .../UnsafeShellCommandConstructionQuery.qll | 24 +-- .../security/dataflow/UrlRedirectQuery.qll | 15 +- .../WeakSensitiveDataHashingQuery.qll | 68 +----- .../python/security/dataflow/XmlBombQuery.qll | 15 +- .../security/dataflow/XpathInjectionQuery.qll | 15 +- .../python/security/dataflow/XxeQuery.qll | 15 +- .../ModificationOfParameterWithDefault.ql | 8 +- .../CWE-020-ExternalAPIs/ExternalAPIs.qll | 23 +- .../UntrustedDataToExternalAPI.ql | 6 +- .../ql/src/Security/CWE-022/PathInjection.ql | 6 +- python/ql/src/Security/CWE-022/TarSlip.ql | 6 +- .../src/Security/CWE-078/CommandInjection.ql | 6 +- .../CWE-078/UnsafeShellCommandConstruction.ql | 8 +- .../ql/src/Security/CWE-079/ReflectedXss.ql | 6 +- .../ql/src/Security/CWE-089/SqlInjection.ql | 6 +- .../ql/src/Security/CWE-090/LdapInjection.ql | 8 +- .../ql/src/Security/CWE-094/CodeInjection.ql | 6 +- .../ql/src/Security/CWE-117/LogInjection.ql | 6 +- .../Security/CWE-209/StackTraceExposure.ql | 6 +- .../src/Security/CWE-285/PamAuthorization.ql | 6 +- .../src/Security/CWE-312/CleartextLogging.ql | 7 +- .../src/Security/CWE-312/CleartextStorage.ql | 7 +- .../CWE-327/WeakSensitiveDataHashing.ql | 42 ++-- .../Security/CWE-502/UnsafeDeserialization.ql | 6 +- python/ql/src/Security/CWE-601/UrlRedirect.ql | 6 +- python/ql/src/Security/CWE-611/Xxe.ql | 6 +- .../ql/src/Security/CWE-643/XpathInjection.ql | 6 +- .../src/Security/CWE-730/PolynomialReDoS.ql | 6 +- .../ql/src/Security/CWE-730/RegexInjection.ql | 6 +- python/ql/src/Security/CWE-776/XmlBomb.ql | 6 +- .../Security/CWE-798/HardcodedCredentials.ql | 17 +- .../CWE-918/FullServerSideRequestForgery.ql | 8 +- .../PartialServerSideRequestForgery.ql | 8 +- .../experimental/Security/CWE-022/ZipSlip.ql | 6 +- .../Security/CWE-022bis/TarSlipImprov.ql | 19 +- .../Security/CWE-022bis/UnsafeUnpack.ql | 6 +- .../Security/CWE-074/paramiko/paramiko.ql | 20 +- .../CWE-079/{EmailXss.ql => ReflectedXSS.ql} | 8 +- .../Security/CWE-113/HeaderInjection.ql | 6 +- .../Security/CWE-1236/CsvInjection.ql | 6 +- .../CWE-176/UnicodeBypassValidation.ql | 6 +- .../CWE-176/UnicodeBypassValidationQuery.qll | 17 +- .../PossibleTimingAttackAgainstHash.ql | 20 +- .../TimingAttackAgainstHash.ql | 17 +- .../TimingAttackAgainstHeaderValue.ql | 22 +- ...ossibleTimingAttackAgainstSensitiveInfo.ql | 20 +- .../TimingAttackAgainstSensitiveInfo.ql | 19 +- .../WebAppConstantSecretKey.ql | 10 +- ...nsafeUsageOfClientSideEncryptionVersion.ql | 10 +- .../Security/CWE-338/InsecureRandomness.ql | 8 +- .../Security/CWE-340/TokenBuiltFromUUID.ql | 20 +- .../ClientSuppliedIpUsedInSecurityCheck.ql | 24 +-- ...ecureAuth.qhelp => LDAPInsecureAuth.qhelp} | 0 ...dapInsecureAuth.ql => LDAPInsecureAuth.ql} | 8 +- .../Security/CWE-614/CookieInjection.ql | 8 +- .../Security/UnsafeUnpackQuery.qll | 13 +- .../semmle/python/libraries/SmtpLib.qll | 15 +- .../python/security/InsecureRandomness.qll | 17 +- ...pInsecureAuth.qll => LDAPInsecureAuth.qll} | 11 +- .../semmle/python/security/TimingAttack.qll | 45 ++-- .../semmle/python/security/ZipSlip.qll | 11 +- .../{EmailXss.qll => ReflectedXSS.qll} | 22 +- .../security/injection/CookieInjection.qll | 11 +- .../security/injection/CsvInjection.qll | 13 +- .../python/security/injection/HTTPHeaders.qll | 11 +- .../ModificationOfParameterWithDefault.qll | 33 +-- .../Security/CWE-022-TarSlip/TarSlip.expected | 4 +- .../DataflowQueryTest.expected | 2 +- .../DataflowQueryTest.ql | 2 +- .../UnsafeUnpack.expected | 126 ++--------- .../CWE-074-paramiko/paramiko.expected | 4 +- .../Security/CWE-079/EmailXss.qlref | 1 - ...mailXss.expected => ReflectedXSS.expected} | 4 +- .../Security/CWE-079/ReflectedXSS.qlref | 1 + ...eTimingAttackAgainstSensitiveInfo.expected | 21 ++ ...uth.expected => LDAPInsecureAuth.expected} | 0 .../LDAPInsecureAuth.qlref | 1 + .../LdapInsecureAuth.qlref | 1 - ...uth.expected => LDAPInsecureAuth.expected} | 0 .../Security/CWE-522/LDAPInsecureAuth.qlref | 1 + .../Security/CWE-522/LdapInsecureAuth.qlref | 1 - .../test.ql | 2 +- .../DataflowQueryTest.ql | 2 +- .../PathInjection.expected | 8 +- .../DataflowQueryTest.ql | 2 +- .../DataflowQueryTest.ql | 2 +- .../StackTraceExposure.expected | 4 +- .../PamAuthorization.expected | 8 +- .../WeakSensitiveDataHashing.expected | 12 +- .../FullServerSideRequestForgery.expected | 196 ++++++++++++++++++ .../PartialServerSideRequestForgery.expected | 106 ++++++++++ 108 files changed, 728 insertions(+), 1032 deletions(-) rename python/ql/src/experimental/Security/CWE-079/{EmailXss.ql => ReflectedXSS.ql} (72%) rename python/ql/src/experimental/Security/CWE-522/{LdapInsecureAuth.qhelp => LDAPInsecureAuth.qhelp} (100%) rename python/ql/src/experimental/Security/CWE-522/{LdapInsecureAuth.ql => LDAPInsecureAuth.ql} (64%) rename python/ql/src/experimental/semmle/python/security/{LdapInsecureAuth.qll => LDAPInsecureAuth.qll} (90%) rename python/ql/src/experimental/semmle/python/security/dataflow/{EmailXss.qll => ReflectedXSS.qll} (51%) delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-079/EmailXss.qlref rename python/ql/test/experimental/query-tests/Security/CWE-079/{EmailXss.expected => ReflectedXSS.expected} (97%) create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-079/ReflectedXSS.qlref rename python/ql/test/experimental/query-tests/Security/CWE-522-global-option/{LdapInsecureAuth.expected => LDAPInsecureAuth.expected} (100%) create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-522-global-option/LDAPInsecureAuth.qlref delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-522-global-option/LdapInsecureAuth.qlref rename python/ql/test/experimental/query-tests/Security/CWE-522/{LdapInsecureAuth.expected => LDAPInsecureAuth.expected} (100%) create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-522/LDAPInsecureAuth.qlref delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-522/LdapInsecureAuth.qlref diff --git a/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingQuery.qll b/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingQuery.qll index 0b0cb046820..7479c24fc53 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingQuery.qll @@ -16,11 +16,9 @@ private import semmle.python.dataflow.new.SensitiveDataSources import CleartextLoggingCustomizations::CleartextLogging /** - * DEPRECATED: Use `CleartextLoggingFlow` module instead. - * * A taint-tracking configuration for detecting "Clear-text logging of sensitive information". */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "CleartextLogging" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -33,14 +31,3 @@ deprecated class Configuration extends TaintTracking::Configuration { node instanceof Sanitizer } } - -private module CleartextLoggingConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } -} - -/** Global taint-tracking for detecting "Clear-text logging of sensitive information" vulnerabilities. */ -module CleartextLoggingFlow = TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/CleartextStorageQuery.qll b/python/ql/lib/semmle/python/security/dataflow/CleartextStorageQuery.qll index ef9c8c13b56..e5320c76d34 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CleartextStorageQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CleartextStorageQuery.qll @@ -16,11 +16,9 @@ private import semmle.python.dataflow.new.SensitiveDataSources import CleartextStorageCustomizations::CleartextStorage /** - * DEPRECATED: Use `CleartextStorageFlow` module instead. - * * A taint-tracking configuration for detecting "Clear-text storage of sensitive information". */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "CleartextStorage" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -33,14 +31,3 @@ deprecated class Configuration extends TaintTracking::Configuration { node instanceof Sanitizer } } - -private module CleartextStorageConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } -} - -/** Global taint-tracking for detecting "Clear-text storage of sensitive information" vulnerabilities. */ -module CleartextStorageFlow = TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/CodeInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/CodeInjectionQuery.qll index 3cdb72c383a..a318ae60aa8 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CodeInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CodeInjectionQuery.qll @@ -12,11 +12,9 @@ import semmle.python.dataflow.new.TaintTracking import CodeInjectionCustomizations::CodeInjection /** - * DEPRECATED: Use `CodeInjectionFlow` module instead. - * * A taint-tracking configuration for detecting "code injection" vulnerabilities. */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "CodeInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -29,14 +27,3 @@ deprecated class Configuration extends TaintTracking::Configuration { guard instanceof SanitizerGuard } } - -private module CodeInjectionConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } -} - -/** Global taint-tracking for detecting "code injection" vulnerabilities. */ -module CodeInjectionFlow = TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/CommandInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/CommandInjectionQuery.qll index 80ca46dafa9..526fd9d0694 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CommandInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CommandInjectionQuery.qll @@ -12,11 +12,9 @@ import semmle.python.dataflow.new.TaintTracking import CommandInjectionCustomizations::CommandInjection /** - * DEPRECATED: Use `CommandInjectionFlow` module instead. - * * A taint-tracking configuration for detecting "command injection" vulnerabilities. */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "CommandInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -29,17 +27,3 @@ deprecated class Configuration extends TaintTracking::Configuration { guard instanceof SanitizerGuard } } - -/** - * A taint-tracking configuration for detecting "command injection" vulnerabilities. - */ -module CommandInjectionConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } -} - -/** Global taint-tracking for detecting "command injection" vulnerabilities. */ -module CommandInjectionFlow = TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/LdapInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/LdapInjectionQuery.qll index 1ebead95418..aa13a8ee6a9 100644 --- a/python/ql/lib/semmle/python/security/dataflow/LdapInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/LdapInjectionQuery.qll @@ -14,12 +14,10 @@ import semmle.python.dataflow.new.RemoteFlowSources import LdapInjectionCustomizations::LdapInjection /** - * DEPRECATED: Use `LdapInjectionDnFlow` module instead. - * * A taint-tracking configuration for detecting LDAP injection vulnerabilities * via the distinguished name (DN) parameter of an LDAP search. */ -deprecated class DnConfiguration extends TaintTracking::Configuration { +class DnConfiguration extends TaintTracking::Configuration { DnConfiguration() { this = "LdapDnInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -33,24 +31,11 @@ deprecated class DnConfiguration extends TaintTracking::Configuration { } } -private module LdapInjectionDnConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof DnSink } - - predicate isBarrier(DataFlow::Node node) { node instanceof DnSanitizer } -} - -/** Global taint-tracking for detecting "LDAP injection via the distinguished name (DN) parameter" vulnerabilities. */ -module LdapInjectionDnFlow = TaintTracking::Global; - /** - * DEPRECATED: Use `LdapInjectionFilterFlow` module instead. - * * A taint-tracking configuration for detecting LDAP injection vulnerabilities * via the filter parameter of an LDAP search. */ -deprecated class FilterConfiguration extends TaintTracking::Configuration { +class FilterConfiguration extends TaintTracking::Configuration { FilterConfiguration() { this = "LdapFilterInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -63,19 +48,3 @@ deprecated class FilterConfiguration extends TaintTracking::Configuration { guard instanceof FilterSanitizerGuard } } - -private module LdapInjectionFilterConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof FilterSink } - - predicate isBarrier(DataFlow::Node node) { node instanceof FilterSanitizer } -} - -/** Global taint-tracking for detecting "LDAP injection via the filter parameter" vulnerabilities. */ -module LdapInjectionFilterFlow = TaintTracking::Global; - -/** Global taint-tracking for detecting "LDAP injection" vulnerabilities. */ -module LdapInjectionFlow = - DataFlow::MergePathGraph; diff --git a/python/ql/lib/semmle/python/security/dataflow/LogInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/LogInjectionQuery.qll index 8f91c6e85ee..4679c2c154b 100644 --- a/python/ql/lib/semmle/python/security/dataflow/LogInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/LogInjectionQuery.qll @@ -1,5 +1,5 @@ /** - * Provides a taint-tracking configuration for tracking "log injection" vulnerabilities. + * Provides a taint-tracking configuration for tracking untrusted user input used in log entries. * * Note, for performance reasons: only import this file if * `LogInjection::Configuration` is needed, otherwise @@ -12,11 +12,9 @@ import semmle.python.dataflow.new.TaintTracking import LogInjectionCustomizations::LogInjection /** - * DEPRECATED: Use `LogInjectionFlow` module instead. - * * A taint-tracking configuration for tracking untrusted user input used in log entries. */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "LogInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -29,14 +27,3 @@ deprecated class Configuration extends TaintTracking::Configuration { guard instanceof SanitizerGuard } } - -private module LogInjectionConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } -} - -/** Global taint-tracking for detecting "log injection" vulnerabilities. */ -module LogInjectionFlow = TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/PamAuthorizationQuery.qll b/python/ql/lib/semmle/python/security/dataflow/PamAuthorizationQuery.qll index 4b150299b31..18dc29a4a71 100644 --- a/python/ql/lib/semmle/python/security/dataflow/PamAuthorizationQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/PamAuthorizationQuery.qll @@ -12,11 +12,9 @@ import semmle.python.dataflow.new.TaintTracking import PamAuthorizationCustomizations::PamAuthorizationCustomizations /** - * DEPRECATED: Use `PamAuthorizationFlow` module instead. - * * A taint-tracking configuration for detecting "PAM Authorization" vulnerabilities. */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "PamAuthorization" } override predicate isSource(DataFlow::Node node) { node instanceof Source } @@ -39,28 +37,3 @@ deprecated class Configuration extends TaintTracking::Configuration { exists(VulnPamAuthCall c | c.getArg(0) = node1 | node2 = c) } } - -private module PamAuthorizationConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - // Models flow from a remotely supplied username field to a PAM `handle`. - // `retval = pam_start(service, username, byref(conv), byref(handle))` - exists(API::CallNode pamStart, DataFlow::Node handle, API::CallNode pointer | - pointer = API::moduleImport("ctypes").getMember(["pointer", "byref"]).getACall() and - pamStart = libPam().getMember("pam_start").getACall() and - pointer = pamStart.getArg(3) and - handle = pointer.getArg(0) and - pamStart.getArg(1) = node1 and - handle = node2 - ) - or - // Flow from handle to the authenticate call in the final step - exists(VulnPamAuthCall c | c.getArg(0) = node1 | node2 = c) - } -} - -/** Global taint-tracking for detecting "PAM Authorization" vulnerabilities. */ -module PamAuthorizationFlow = TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/PathInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/PathInjectionQuery.qll index b185098dcb8..5616a94465a 100644 --- a/python/ql/lib/semmle/python/security/dataflow/PathInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/PathInjectionQuery.qll @@ -13,8 +13,6 @@ import semmle.python.dataflow.new.TaintTracking import PathInjectionCustomizations::PathInjection /** - * DEPRECATED: Use `PathInjectionFlow` module instead. - * * A taint-tracking configuration for detecting "path injection" vulnerabilities. * * This configuration uses two flow states, `NotNormalized` and `NormalizedUnchecked`, @@ -27,7 +25,7 @@ import PathInjectionCustomizations::PathInjection * * Such checks are ineffective in the `NotNormalized` state. */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "PathInjection" } override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { @@ -76,52 +74,3 @@ class NotNormalized extends DataFlow::FlowState { class NormalizedUnchecked extends DataFlow::FlowState { NormalizedUnchecked() { this = "NormalizedUnchecked" } } - -/** - * This configuration uses two flow states, `NotNormalized` and `NormalizedUnchecked`, - * to track the requirement that a file path must be first normalized and then checked - * before it is safe to use. - * - * At sources, paths are assumed not normalized. At normalization points, they change - * state to `NormalizedUnchecked` after which they can be made safe by an appropriate - * check of the prefix. - * - * Such checks are ineffective in the `NotNormalized` state. - */ -module PathInjectionConfig implements DataFlow::StateConfigSig { - class FlowState = DataFlow::FlowState; - - predicate isSource(DataFlow::Node source, FlowState state) { - source instanceof Source and state instanceof NotNormalized - } - - predicate isSink(DataFlow::Node sink, FlowState state) { - sink instanceof Sink and - ( - state instanceof NotNormalized or - state instanceof NormalizedUnchecked - ) - } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } - - predicate isBarrier(DataFlow::Node node, FlowState state) { - // Block `NotNormalized` paths here, since they change state to `NormalizedUnchecked` - node instanceof Path::PathNormalization and - state instanceof NotNormalized - or - node instanceof Path::SafeAccessCheck and - state instanceof NormalizedUnchecked - } - - predicate isAdditionalFlowStep( - DataFlow::Node nodeFrom, FlowState stateFrom, DataFlow::Node nodeTo, FlowState stateTo - ) { - nodeFrom = nodeTo.(Path::PathNormalization).getPathArg() and - stateFrom instanceof NotNormalized and - stateTo instanceof NormalizedUnchecked - } -} - -/** Global taint-tracking for detecting "path injection" vulnerabilities. */ -module PathInjectionFlow = TaintTracking::GlobalWithState; diff --git a/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSCustomizations.qll index a6ba053e2d2..09d787de57f 100644 --- a/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSCustomizations.qll @@ -6,6 +6,7 @@ private import python private import semmle.python.dataflow.new.DataFlow +private import semmle.python.dataflow.new.DataFlow2 private import semmle.python.dataflow.new.TaintTracking private import semmle.python.Concepts private import semmle.python.dataflow.new.RemoteFlowSources diff --git a/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSQuery.qll b/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSQuery.qll index 2279814e49e..d9fd1e843e8 100644 --- a/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSQuery.qll @@ -12,11 +12,9 @@ import semmle.python.dataflow.new.TaintTracking import PolynomialReDoSCustomizations::PolynomialReDoS /** - * DEPRECATED: Use `PolynomialReDoSFlow` module instead. - * * A taint-tracking configuration for detecting "polynomial regular expression denial of service (ReDoS)" vulnerabilities. */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "PolynomialReDoS" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -29,14 +27,3 @@ deprecated class Configuration extends TaintTracking::Configuration { guard instanceof SanitizerGuard } } - -private module PolynomialReDoSConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } -} - -/** Global taint-tracking for detecting "polynomial regular expression denial of service (ReDoS)" vulnerabilities. */ -module PolynomialReDoSFlow = TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/ReflectedXssQuery.qll b/python/ql/lib/semmle/python/security/dataflow/ReflectedXssQuery.qll index d136c9d16b8..d150c80ffb1 100644 --- a/python/ql/lib/semmle/python/security/dataflow/ReflectedXssQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/ReflectedXssQuery.qll @@ -12,11 +12,9 @@ import semmle.python.dataflow.new.TaintTracking import ReflectedXSSCustomizations::ReflectedXss /** - * DEPRECATED: Use `ReflectedXssFlow` module instead. - * * A taint-tracking configuration for detecting "reflected server-side cross-site scripting" vulnerabilities. */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "ReflectedXSS" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -29,14 +27,3 @@ deprecated class Configuration extends TaintTracking::Configuration { guard instanceof SanitizerGuard } } - -private module ReflectedXssConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } -} - -/** Global taint-tracking for detecting "reflected server-side cross-site scripting" vulnerabilities. */ -module ReflectedXssFlow = TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/RegexInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/RegexInjectionQuery.qll index 168091bf212..c8287b22c75 100644 --- a/python/ql/lib/semmle/python/security/dataflow/RegexInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/RegexInjectionQuery.qll @@ -1,5 +1,5 @@ /** - * Provides a taint-tracking configuration for detecting "regular expression injection" + * Provides a taint-tracking configuration for detecting regular expression injection * vulnerabilities. * * Note, for performance reasons: only import this file if @@ -13,11 +13,9 @@ import semmle.python.dataflow.new.TaintTracking import RegexInjectionCustomizations::RegexInjection /** - * DEPRECATED: Use `RegexInjectionFlow` module instead. - * * A taint-tracking configuration for detecting "reflected server-side cross-site scripting" vulnerabilities. */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "RegexInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -30,14 +28,3 @@ deprecated class Configuration extends TaintTracking::Configuration { guard instanceof SanitizerGuard } } - -private module RegexInjectionConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } -} - -/** Global taint-tracking for detecting "regular expression injection" vulnerabilities. */ -module RegexInjectionFlow = TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll b/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll index a6c08185bd1..36ec416cca2 100644 --- a/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll @@ -13,8 +13,6 @@ import semmle.python.Concepts import ServerSideRequestForgeryCustomizations::ServerSideRequestForgery /** - * DEPRECATED: Use `FullServerSideRequestForgeryFlow` module instead. - * * A taint-tracking configuration for detecting "Server-side request forgery" vulnerabilities. * * This configuration has a sanitizer to limit results to cases where attacker has full control of URL. @@ -23,7 +21,7 @@ import ServerSideRequestForgeryCustomizations::ServerSideRequestForgery * You should use the `fullyControlledRequest` to only select results where all * URL parts are fully controlled. */ -deprecated class FullServerSideRequestForgeryConfiguration extends TaintTracking::Configuration { +class FullServerSideRequestForgeryConfiguration extends TaintTracking::Configuration { FullServerSideRequestForgeryConfiguration() { this = "FullServerSideRequestForgery" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -41,51 +39,24 @@ deprecated class FullServerSideRequestForgeryConfiguration extends TaintTracking } } -/** - * This configuration has a sanitizer to limit results to cases where attacker has full control of URL. - * See `PartialServerSideRequestForgery` for a variant without this requirement. - * - * You should use the `fullyControlledRequest` to only select results where all - * URL parts are fully controlled. - */ -private module FullServerSideRequestForgeryConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { - node instanceof Sanitizer - or - node instanceof FullUrlControlSanitizer - } -} - -/** - * Global taint-tracking for detecting "Full server-side request forgery" vulnerabilities. - * - * You should use the `fullyControlledRequest` to only select results where all - * URL parts are fully controlled. - */ -module FullServerSideRequestForgeryFlow = TaintTracking::Global; - /** * Holds if all URL parts of `request` is fully user controlled. */ predicate fullyControlledRequest(Http::Client::Request request) { - forall(DataFlow::Node urlPart | urlPart = request.getAUrlPart() | - FullServerSideRequestForgeryFlow::flow(_, urlPart) + exists(FullServerSideRequestForgeryConfiguration fullConfig | + forall(DataFlow::Node urlPart | urlPart = request.getAUrlPart() | + fullConfig.hasFlow(_, urlPart) + ) ) } /** - * DEPRECATED: Use `FullServerSideRequestForgeryFlow` module instead. - * * A taint-tracking configuration for detecting "Server-side request forgery" vulnerabilities. * * This configuration has results, even when the attacker does not have full control over the URL. * See `FullServerSideRequestForgeryConfiguration`, and the `fullyControlledRequest` predicate. */ -deprecated class PartialServerSideRequestForgeryConfiguration extends TaintTracking::Configuration { +class PartialServerSideRequestForgeryConfiguration extends TaintTracking::Configuration { PartialServerSideRequestForgeryConfiguration() { this = "PartialServerSideRequestForgery" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -98,21 +69,3 @@ deprecated class PartialServerSideRequestForgeryConfiguration extends TaintTrack guard instanceof SanitizerGuard } } - -/** - * This configuration has results, even when the attacker does not have full control over the URL. - * See `FullServerSideRequestForgeryConfiguration`, and the `fullyControlledRequest` predicate. - */ -private module PartialServerSideRequestForgeryConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } -} - -/** - * Global taint-tracking for detecting "partial server-side request forgery" vulnerabilities. - */ -module PartialServerSideRequestForgeryFlow = - TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/SqlInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/SqlInjectionQuery.qll index 9b78686fed3..23e6b91a0ef 100644 --- a/python/ql/lib/semmle/python/security/dataflow/SqlInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/SqlInjectionQuery.qll @@ -12,11 +12,9 @@ import semmle.python.dataflow.new.TaintTracking import SqlInjectionCustomizations::SqlInjection /** - * DEPRECATED: Use `SqlInjectionFlow` module instead. - * * A taint-tracking configuration for detecting "SQL injection" vulnerabilities. */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "SqlInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -29,14 +27,3 @@ deprecated class Configuration extends TaintTracking::Configuration { guard instanceof SanitizerGuard } } - -private module SqlInjectionConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } -} - -/** Global taint-tracking for detecting "SQL injection" vulnerabilities. */ -module SqlInjectionFlow = TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/StackTraceExposureQuery.qll b/python/ql/lib/semmle/python/security/dataflow/StackTraceExposureQuery.qll index 22404903c48..3975985fce1 100644 --- a/python/ql/lib/semmle/python/security/dataflow/StackTraceExposureQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/StackTraceExposureQuery.qll @@ -12,11 +12,9 @@ import semmle.python.dataflow.new.TaintTracking import StackTraceExposureCustomizations::StackTraceExposure /** - * DEPRECATED: Use `StackTraceExposureFlow` module instead. - * * A taint-tracking configuration for detecting "stack trace exposure" vulnerabilities. */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "StackTraceExposure" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -38,23 +36,3 @@ deprecated class Configuration extends TaintTracking::Configuration { ) } } - -private module StackTraceExposureConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } - - // A stack trace is accessible as the `__traceback__` attribute of a caught exception. - // see https://docs.python.org/3/reference/datamodel.html#traceback-objects - predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - exists(DataFlow::AttrRead attr | attr.getAttributeName() = "__traceback__" | - nodeFrom = attr.getObject() and - nodeTo = attr - ) - } -} - -/** Global taint-tracking for detecting "stack trace exposure" vulnerabilities. */ -module StackTraceExposureFlow = TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll index 7bb008f1afb..6cf41742a66 100644 --- a/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll @@ -1,5 +1,5 @@ /** - * Provides a taint-tracking configuration for detecting "tar slip" vulnerabilities. + * Provides a taint-tracking configuration for detecting "command injection" vulnerabilities. * * Note, for performance reasons: only import this file if * `TarSlip::Configuration` is needed, otherwise @@ -12,11 +12,9 @@ import semmle.python.dataflow.new.TaintTracking import TarSlipCustomizations::TarSlip /** - * DEPRECATED: Use `TarSlipFlow` module instead. - * - * A taint-tracking configuration for detecting "tar slip" vulnerabilities. + * A taint-tracking configuration for detecting "command injection" vulnerabilities. */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "TarSlip" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -25,14 +23,3 @@ deprecated class Configuration extends TaintTracking::Configuration { override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } } - -private module TarSlipConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } -} - -/** Global taint-tracking for detecting "tar slip" vulnerabilities. */ -module TarSlipFlow = TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationQuery.qll b/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationQuery.qll index d9dfde62bcb..0a2046b8a4b 100644 --- a/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationQuery.qll @@ -12,11 +12,9 @@ import semmle.python.dataflow.new.TaintTracking import UnsafeDeserializationCustomizations::UnsafeDeserialization /** - * DEPRECATED: Use `UnsafeDeserializationFlow` module instead. - * * A taint-tracking configuration for detecting "code execution from deserialization" vulnerabilities. */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "UnsafeDeserialization" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -29,14 +27,3 @@ deprecated class Configuration extends TaintTracking::Configuration { guard instanceof SanitizerGuard } } - -private module UnsafeDeserializationConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } -} - -/** Global taint-tracking for detecting "code execution from deserialization" vulnerabilities. */ -module UnsafeDeserializationFlow = TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll index 73205fdeb28..80781a97ac6 100644 --- a/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll @@ -14,11 +14,9 @@ private import CommandInjectionCustomizations::CommandInjection as CommandInject private import semmle.python.dataflow.new.BarrierGuards /** - * DEPRECATED: Use `UnsafeShellCommandConstructionFlow` module instead. - * * A taint-tracking configuration for detecting shell command constructed from library input vulnerabilities. */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "UnsafeShellCommandConstruction" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -35,23 +33,3 @@ deprecated class Configuration extends TaintTracking::Configuration { result instanceof DataFlow::FeatureHasSourceCallContext } } - -/** - * A taint-tracking configuration for detecting "shell command constructed from library input" vulnerabilities. - */ -module UnsafeShellCommandConstructionConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { - node instanceof CommandInjection::Sanitizer // using all sanitizers from `py/command-injection` - } - - // override to require the path doesn't have unmatched return steps - DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext } -} - -/** Global taint-tracking for detecting "shell command constructed from library input" vulnerabilities. */ -module UnsafeShellCommandConstructionFlow = - TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/UrlRedirectQuery.qll b/python/ql/lib/semmle/python/security/dataflow/UrlRedirectQuery.qll index cb1adc21135..599f08d133a 100644 --- a/python/ql/lib/semmle/python/security/dataflow/UrlRedirectQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/UrlRedirectQuery.qll @@ -12,11 +12,9 @@ import semmle.python.dataflow.new.TaintTracking import UrlRedirectCustomizations::UrlRedirect /** - * DEPRECATED: Use `UrlRedirectFlow` module instead. - * * A taint-tracking configuration for detecting "URL redirection" vulnerabilities. */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "UrlRedirect" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -29,14 +27,3 @@ deprecated class Configuration extends TaintTracking::Configuration { guard instanceof SanitizerGuard } } - -private module UrlRedirectConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } -} - -/** Global taint-tracking for detecting "URL redirection" vulnerabilities. */ -module UrlRedirectFlow = TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashingQuery.qll b/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashingQuery.qll index 9e2803b3369..f7aec512772 100644 --- a/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashingQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashingQuery.qll @@ -24,12 +24,10 @@ module NormalHashFunction { import WeakSensitiveDataHashingCustomizations::NormalHashFunction /** - * DEPRECATED: Use `Flow` module instead. - * * A taint-tracking configuration for detecting use of a broken or weak * cryptographic hashing algorithm on sensitive data. */ - deprecated class Configuration extends TaintTracking::Configuration { + class Configuration extends TaintTracking::Configuration { Configuration() { this = "NormalHashFunction" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -46,21 +44,6 @@ module NormalHashFunction { sensitiveDataExtraStepForCalls(node1, node2) } } - - private module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } - - predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - sensitiveDataExtraStepForCalls(node1, node2) - } - } - - /** Global taint-tracking for detecting "use of a broken or weak cryptographic hashing algorithm on sensitive data" vulnerabilities. */ - module Flow = TaintTracking::Global; } /** @@ -74,15 +57,13 @@ module ComputationallyExpensiveHashFunction { import WeakSensitiveDataHashingCustomizations::ComputationallyExpensiveHashFunction /** - * DEPRECATED: Use `Flow` module instead. - * * A taint-tracking configuration for detecting use of a broken or weak * cryptographic hashing algorithm on passwords. * * Passwords has stricter requirements on the hashing algorithm used (must be * computationally expensive to prevent brute-force attacks). */ - deprecated class Configuration extends TaintTracking::Configuration { + class Configuration extends TaintTracking::Configuration { Configuration() { this = "ComputationallyExpensiveHashFunction" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -99,49 +80,4 @@ module ComputationallyExpensiveHashFunction { sensitiveDataExtraStepForCalls(node1, node2) } } - - /** - * Passwords has stricter requirements on the hashing algorithm used (must be - * computationally expensive to prevent brute-force attacks). - */ - private module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } - - predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - sensitiveDataExtraStepForCalls(node1, node2) - } - } - - /** Global taint-tracking for detecting "use of a broken or weak cryptographic hashing algorithm on passwords" vulnerabilities. */ - module Flow = TaintTracking::Global; -} - -/** - * Global taint-tracking for detecting both variants of "use of a broken or weak - * cryptographic hashing algorithm on sensitive data" vulnerabilities. - * - * See convenience predicates `normalHashFunctionFlowPath` and - * `computationallyExpensiveHashFunctionFlowPath`. - */ -module WeakSensitiveDataHashingFlow = - DataFlow::MergePathGraph; - -/** Holds if data can flow from `source` to `sink` with `NormalHashFunction::Flow`. */ -predicate normalHashFunctionFlowPath( - WeakSensitiveDataHashingFlow::PathNode source, WeakSensitiveDataHashingFlow::PathNode sink -) { - NormalHashFunction::Flow::flowPath(source.asPathNode1(), sink.asPathNode1()) -} - -/** Holds if data can flow from `source` to `sink` with `ComputationallyExpensiveHashFunction::Flow`. */ -predicate computationallyExpensiveHashFunctionFlowPath( - WeakSensitiveDataHashingFlow::PathNode source, WeakSensitiveDataHashingFlow::PathNode sink -) { - ComputationallyExpensiveHashFunction::Flow::flowPath(source.asPathNode2(), sink.asPathNode2()) } diff --git a/python/ql/lib/semmle/python/security/dataflow/XmlBombQuery.qll b/python/ql/lib/semmle/python/security/dataflow/XmlBombQuery.qll index dcf3939bc78..d0c0b85d84f 100644 --- a/python/ql/lib/semmle/python/security/dataflow/XmlBombQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/XmlBombQuery.qll @@ -12,11 +12,9 @@ import semmle.python.dataflow.new.TaintTracking import XmlBombCustomizations::XmlBomb /** - * DEPRECATED: Use `XmlBombFlow` module instead. - * * A taint-tracking configuration for detecting "XML bomb" vulnerabilities. */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "XmlBomb" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -28,14 +26,3 @@ deprecated class Configuration extends TaintTracking::Configuration { node instanceof Sanitizer } } - -private module XmlBombConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } -} - -/** Global taint-tracking for detecting "XML bomb" vulnerabilities. */ -module XmlBombFlow = TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/XpathInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/XpathInjectionQuery.qll index 34a34e49ba2..aa5a27c5392 100644 --- a/python/ql/lib/semmle/python/security/dataflow/XpathInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/XpathInjectionQuery.qll @@ -12,11 +12,9 @@ import semmle.python.dataflow.new.TaintTracking import XpathInjectionCustomizations::XpathInjection /** - * DEPRECATED: Use `XpathInjectionFlow` module instead. - * * A taint-tracking configuration for detecting "Xpath Injection" vulnerabilities. */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "Xpath Injection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -29,14 +27,3 @@ deprecated class Configuration extends TaintTracking::Configuration { guard instanceof SanitizerGuard } } - -private module XpathInjectionConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } -} - -/** Global taint-tracking for detecting "Xpath Injection" vulnerabilities. */ -module XpathInjectionFlow = TaintTracking::Global; diff --git a/python/ql/lib/semmle/python/security/dataflow/XxeQuery.qll b/python/ql/lib/semmle/python/security/dataflow/XxeQuery.qll index 8d85d275f1e..dd2409f2a3c 100644 --- a/python/ql/lib/semmle/python/security/dataflow/XxeQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/XxeQuery.qll @@ -12,11 +12,9 @@ import semmle.python.dataflow.new.TaintTracking import XxeCustomizations::Xxe /** - * DEPRECATED: Use `XxeFlow` module instead. - * * A taint-tracking configuration for detecting "XML External Entity (XXE)" vulnerabilities. */ -deprecated class Configuration extends TaintTracking::Configuration { +class Configuration extends TaintTracking::Configuration { Configuration() { this = "Xxe" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -28,14 +26,3 @@ deprecated class Configuration extends TaintTracking::Configuration { node instanceof Sanitizer } } - -private module XxeConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } -} - -/** Global taint-tracking for detecting "XML External Entity (XXE)" vulnerabilities. */ -module XxeFlow = TaintTracking::Global; diff --git a/python/ql/src/Functions/ModificationOfParameterWithDefault.ql b/python/ql/src/Functions/ModificationOfParameterWithDefault.ql index 3c601091694..88b346fd2a0 100644 --- a/python/ql/src/Functions/ModificationOfParameterWithDefault.ql +++ b/python/ql/src/Functions/ModificationOfParameterWithDefault.ql @@ -13,11 +13,11 @@ import python import semmle.python.functions.ModificationOfParameterWithDefault -import ModificationOfParameterWithDefault::Flow::PathGraph +import DataFlow::PathGraph from - ModificationOfParameterWithDefault::Flow::PathNode source, - ModificationOfParameterWithDefault::Flow::PathNode sink -where ModificationOfParameterWithDefault::Flow::flowPath(source, sink) + ModificationOfParameterWithDefault::Configuration config, DataFlow::PathNode source, + DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "This expression mutates a $@.", source.getNode(), "default value" diff --git a/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll b/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll index 82e3c3121d0..766cf6845af 100644 --- a/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll +++ b/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll @@ -167,12 +167,8 @@ class ExternalApiDataNode extends DataFlow::Node { } } -/** - * DEPRECATED: Use `XmlBombFlow` module instead. - * - * A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. - */ -deprecated class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration { +/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */ +class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration { UntrustedDataToExternalApiConfig() { this = "UntrustedDataToExternalAPIConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } @@ -180,21 +176,14 @@ deprecated class UntrustedDataToExternalApiConfig extends TaintTracking::Configu override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode } } -private module UntrustedDataToExternalApiConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - - predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode } -} - -/** Global taint-tracking from `RemoteFlowSource`s to `ExternalApiDataNode`s. */ -module UntrustedDataToExternalApiFlow = TaintTracking::Global; - /** A node representing untrusted data being passed to an external API. */ class UntrustedExternalApiDataNode extends ExternalApiDataNode { - UntrustedExternalApiDataNode() { UntrustedDataToExternalApiFlow::flow(_, this) } + UntrustedExternalApiDataNode() { any(UntrustedDataToExternalApiConfig c).hasFlow(_, this) } /** Gets a source of untrusted data which is passed to this external API data node. */ - DataFlow::Node getAnUntrustedSource() { UntrustedDataToExternalApiFlow::flow(result, this) } + DataFlow::Node getAnUntrustedSource() { + any(UntrustedDataToExternalApiConfig c).hasFlow(result, this) + } } /** An external API which is used with untrusted data. */ diff --git a/python/ql/src/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.ql b/python/ql/src/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.ql index f5706ccc3a6..6426854222c 100644 --- a/python/ql/src/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.ql +++ b/python/ql/src/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.ql @@ -11,14 +11,14 @@ import python import ExternalAPIs -import UntrustedDataToExternalApiFlow::PathGraph +import DataFlow::PathGraph from - UntrustedDataToExternalApiFlow::PathNode source, UntrustedDataToExternalApiFlow::PathNode sink, + UntrustedDataToExternalApiConfig config, DataFlow::PathNode source, DataFlow::PathNode sink, ExternalApiUsedWithUntrustedData externalApi where sink.getNode() = externalApi.getUntrustedDataNode() and - UntrustedDataToExternalApiFlow::flowPath(source, sink) + config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Call to " + externalApi.toString() + " with untrusted data from $@.", source.getNode(), source.toString() diff --git a/python/ql/src/Security/CWE-022/PathInjection.ql b/python/ql/src/Security/CWE-022/PathInjection.ql index 1686dec7c91..8548c815fe4 100644 --- a/python/ql/src/Security/CWE-022/PathInjection.ql +++ b/python/ql/src/Security/CWE-022/PathInjection.ql @@ -18,9 +18,9 @@ import python import semmle.python.security.dataflow.PathInjectionQuery -import PathInjectionFlow::PathGraph +import DataFlow::PathGraph -from PathInjectionFlow::PathNode source, PathInjectionFlow::PathNode sink -where PathInjectionFlow::flowPath(source, sink) +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "This path depends on a $@.", source.getNode(), "user-provided value" diff --git a/python/ql/src/Security/CWE-022/TarSlip.ql b/python/ql/src/Security/CWE-022/TarSlip.ql index cb0cd54d19b..647b41756f8 100644 --- a/python/ql/src/Security/CWE-022/TarSlip.ql +++ b/python/ql/src/Security/CWE-022/TarSlip.ql @@ -14,9 +14,9 @@ import python import semmle.python.security.dataflow.TarSlipQuery -import TarSlipFlow::PathGraph +import DataFlow::PathGraph -from TarSlipFlow::PathNode source, TarSlipFlow::PathNode sink -where TarSlipFlow::flowPath(source, sink) +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "This file extraction depends on a $@.", source.getNode(), "potentially untrusted source" diff --git a/python/ql/src/Security/CWE-078/CommandInjection.ql b/python/ql/src/Security/CWE-078/CommandInjection.ql index 1c2c5125b32..f8c48714e1a 100644 --- a/python/ql/src/Security/CWE-078/CommandInjection.ql +++ b/python/ql/src/Security/CWE-078/CommandInjection.ql @@ -16,9 +16,9 @@ import python import semmle.python.security.dataflow.CommandInjectionQuery -import CommandInjectionFlow::PathGraph +import DataFlow::PathGraph -from CommandInjectionFlow::PathNode source, CommandInjectionFlow::PathNode sink -where CommandInjectionFlow::flowPath(source, sink) +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "This command line depends on a $@.", source.getNode(), "user-provided value" diff --git a/python/ql/src/Security/CWE-078/UnsafeShellCommandConstruction.ql b/python/ql/src/Security/CWE-078/UnsafeShellCommandConstruction.ql index 561bcf7dd49..10f4b771261 100644 --- a/python/ql/src/Security/CWE-078/UnsafeShellCommandConstruction.ql +++ b/python/ql/src/Security/CWE-078/UnsafeShellCommandConstruction.ql @@ -16,13 +16,11 @@ import python import semmle.python.security.dataflow.UnsafeShellCommandConstructionQuery -import UnsafeShellCommandConstructionFlow::PathGraph +import DataFlow::PathGraph -from - UnsafeShellCommandConstructionFlow::PathNode source, - UnsafeShellCommandConstructionFlow::PathNode sink, Sink sinkNode +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink, Sink sinkNode where - UnsafeShellCommandConstructionFlow::flowPath(source, sink) and + config.hasFlowPath(source, sink) and sinkNode = sink.getNode() select sinkNode.getStringConstruction(), source, sink, "This " + sinkNode.describe() + " which depends on $@ is later used in a $@.", source.getNode(), diff --git a/python/ql/src/Security/CWE-079/ReflectedXss.ql b/python/ql/src/Security/CWE-079/ReflectedXss.ql index 11ebad00e37..1189e35be67 100644 --- a/python/ql/src/Security/CWE-079/ReflectedXss.ql +++ b/python/ql/src/Security/CWE-079/ReflectedXss.ql @@ -15,9 +15,9 @@ import python import semmle.python.security.dataflow.ReflectedXssQuery -import ReflectedXssFlow::PathGraph +import DataFlow::PathGraph -from ReflectedXssFlow::PathNode source, ReflectedXssFlow::PathNode sink -where ReflectedXssFlow::flowPath(source, sink) +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Cross-site scripting vulnerability due to a $@.", source.getNode(), "user-provided value" diff --git a/python/ql/src/Security/CWE-089/SqlInjection.ql b/python/ql/src/Security/CWE-089/SqlInjection.ql index e6861e86066..5e910cf3edf 100644 --- a/python/ql/src/Security/CWE-089/SqlInjection.ql +++ b/python/ql/src/Security/CWE-089/SqlInjection.ql @@ -13,9 +13,9 @@ import python import semmle.python.security.dataflow.SqlInjectionQuery -import SqlInjectionFlow::PathGraph +import DataFlow::PathGraph -from SqlInjectionFlow::PathNode source, SqlInjectionFlow::PathNode sink -where SqlInjectionFlow::flowPath(source, sink) +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "This SQL query depends on a $@.", source.getNode(), "user-provided value" diff --git a/python/ql/src/Security/CWE-090/LdapInjection.ql b/python/ql/src/Security/CWE-090/LdapInjection.ql index f4943f8a8dc..efcf52eba41 100644 --- a/python/ql/src/Security/CWE-090/LdapInjection.ql +++ b/python/ql/src/Security/CWE-090/LdapInjection.ql @@ -14,14 +14,14 @@ // Determine precision above import python import semmle.python.security.dataflow.LdapInjectionQuery -import LdapInjectionFlow::PathGraph +import DataFlow::PathGraph -from LdapInjectionFlow::PathNode source, LdapInjectionFlow::PathNode sink, string parameterName +from DataFlow::PathNode source, DataFlow::PathNode sink, string parameterName where - LdapInjectionDnFlow::flowPath(source.asPathNode1(), sink.asPathNode1()) and + any(DnConfiguration dnConfig).hasFlowPath(source, sink) and parameterName = "DN" or - LdapInjectionFilterFlow::flowPath(source.asPathNode2(), sink.asPathNode2()) and + any(FilterConfiguration filterConfig).hasFlowPath(source, sink) and parameterName = "filter" select sink.getNode(), source, sink, "LDAP query parameter (" + parameterName + ") depends on a $@.", source.getNode(), diff --git a/python/ql/src/Security/CWE-094/CodeInjection.ql b/python/ql/src/Security/CWE-094/CodeInjection.ql index d0683c7ffca..5e5c06b68b7 100644 --- a/python/ql/src/Security/CWE-094/CodeInjection.ql +++ b/python/ql/src/Security/CWE-094/CodeInjection.ql @@ -16,9 +16,9 @@ import python import semmle.python.security.dataflow.CodeInjectionQuery -import CodeInjectionFlow::PathGraph +import DataFlow::PathGraph -from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink -where CodeInjectionFlow::flowPath(source, sink) +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "This code execution depends on a $@.", source.getNode(), "user-provided value" diff --git a/python/ql/src/Security/CWE-117/LogInjection.ql b/python/ql/src/Security/CWE-117/LogInjection.ql index f1b72faaccb..3c380321af2 100644 --- a/python/ql/src/Security/CWE-117/LogInjection.ql +++ b/python/ql/src/Security/CWE-117/LogInjection.ql @@ -13,9 +13,9 @@ import python import semmle.python.security.dataflow.LogInjectionQuery -import LogInjectionFlow::PathGraph +import DataFlow::PathGraph -from LogInjectionFlow::PathNode source, LogInjectionFlow::PathNode sink -where LogInjectionFlow::flowPath(source, sink) +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "This log entry depends on a $@.", source.getNode(), "user-provided value" diff --git a/python/ql/src/Security/CWE-209/StackTraceExposure.ql b/python/ql/src/Security/CWE-209/StackTraceExposure.ql index 1feed997e25..7b8cf74c597 100644 --- a/python/ql/src/Security/CWE-209/StackTraceExposure.ql +++ b/python/ql/src/Security/CWE-209/StackTraceExposure.ql @@ -15,10 +15,10 @@ import python import semmle.python.security.dataflow.StackTraceExposureQuery -import StackTraceExposureFlow::PathGraph +import DataFlow::PathGraph -from StackTraceExposureFlow::PathNode source, StackTraceExposureFlow::PathNode sink -where StackTraceExposureFlow::flowPath(source, sink) +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "$@ flows to this location and may be exposed to an external user.", source.getNode(), "Stack trace information" diff --git a/python/ql/src/Security/CWE-285/PamAuthorization.ql b/python/ql/src/Security/CWE-285/PamAuthorization.ql index 1da0b8c9b10..43cbc33917a 100644 --- a/python/ql/src/Security/CWE-285/PamAuthorization.ql +++ b/python/ql/src/Security/CWE-285/PamAuthorization.ql @@ -11,12 +11,12 @@ */ import python -import PamAuthorizationFlow::PathGraph +import DataFlow::PathGraph import semmle.python.ApiGraphs import semmle.python.security.dataflow.PamAuthorizationQuery -from PamAuthorizationFlow::PathNode source, PamAuthorizationFlow::PathNode sink -where PamAuthorizationFlow::flowPath(source, sink) +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "This PAM authentication depends on a $@, and 'pam_acct_mgmt' is not called afterwards.", source.getNode(), "user-provided value" diff --git a/python/ql/src/Security/CWE-312/CleartextLogging.ql b/python/ql/src/Security/CWE-312/CleartextLogging.ql index 500a2b5f9b7..0c2591eaec4 100644 --- a/python/ql/src/Security/CWE-312/CleartextLogging.ql +++ b/python/ql/src/Security/CWE-312/CleartextLogging.ql @@ -15,13 +15,12 @@ import python private import semmle.python.dataflow.new.DataFlow -import CleartextLoggingFlow::PathGraph +import DataFlow::PathGraph import semmle.python.security.dataflow.CleartextLoggingQuery -from - CleartextLoggingFlow::PathNode source, CleartextLoggingFlow::PathNode sink, string classification +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink, string classification where - CleartextLoggingFlow::flowPath(source, sink) and + config.hasFlowPath(source, sink) and classification = source.getNode().(Source).getClassification() select sink.getNode(), source, sink, "This expression logs $@ as clear text.", source.getNode(), "sensitive data (" + classification + ")" diff --git a/python/ql/src/Security/CWE-312/CleartextStorage.ql b/python/ql/src/Security/CWE-312/CleartextStorage.ql index f83097d6e0b..9a8d5de3331 100644 --- a/python/ql/src/Security/CWE-312/CleartextStorage.ql +++ b/python/ql/src/Security/CWE-312/CleartextStorage.ql @@ -15,13 +15,12 @@ import python private import semmle.python.dataflow.new.DataFlow -import CleartextStorageFlow::PathGraph +import DataFlow::PathGraph import semmle.python.security.dataflow.CleartextStorageQuery -from - CleartextStorageFlow::PathNode source, CleartextStorageFlow::PathNode sink, string classification +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink, string classification where - CleartextStorageFlow::flowPath(source, sink) and + config.hasFlowPath(source, sink) and classification = source.getNode().(Source).getClassification() select sink.getNode(), source, sink, "This expression stores $@ as clear text.", source.getNode(), "sensitive data (" + classification + ")" diff --git a/python/ql/src/Security/CWE-327/WeakSensitiveDataHashing.ql b/python/ql/src/Security/CWE-327/WeakSensitiveDataHashing.ql index ef72ae1fdbc..ce46a21fe71 100644 --- a/python/ql/src/Security/CWE-327/WeakSensitiveDataHashing.ql +++ b/python/ql/src/Security/CWE-327/WeakSensitiveDataHashing.ql @@ -16,29 +16,33 @@ import python import semmle.python.security.dataflow.WeakSensitiveDataHashingQuery import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking -import WeakSensitiveDataHashingFlow::PathGraph +import DataFlow::PathGraph from - WeakSensitiveDataHashingFlow::PathNode source, WeakSensitiveDataHashingFlow::PathNode sink, - string ending, string algorithmName, string classification + DataFlow::PathNode source, DataFlow::PathNode sink, string ending, string algorithmName, + string classification where - normalHashFunctionFlowPath(source, sink) and - algorithmName = sink.getNode().(NormalHashFunction::Sink).getAlgorithmName() and - classification = source.getNode().(NormalHashFunction::Source).getClassification() and - ending = "." - or - computationallyExpensiveHashFunctionFlowPath(source, sink) and - algorithmName = sink.getNode().(ComputationallyExpensiveHashFunction::Sink).getAlgorithmName() and - classification = - source.getNode().(ComputationallyExpensiveHashFunction::Source).getClassification() and - ( - sink.getNode().(ComputationallyExpensiveHashFunction::Sink).isComputationallyExpensive() and + exists(NormalHashFunction::Configuration config | + config.hasFlowPath(source, sink) and + algorithmName = sink.getNode().(NormalHashFunction::Sink).getAlgorithmName() and + classification = source.getNode().(NormalHashFunction::Source).getClassification() and ending = "." - or - not sink.getNode().(ComputationallyExpensiveHashFunction::Sink).isComputationallyExpensive() and - ending = - " for " + classification + - " hashing, since it is not a computationally expensive hash function." + ) + or + exists(ComputationallyExpensiveHashFunction::Configuration config | + config.hasFlowPath(source, sink) and + algorithmName = sink.getNode().(ComputationallyExpensiveHashFunction::Sink).getAlgorithmName() and + classification = + source.getNode().(ComputationallyExpensiveHashFunction::Source).getClassification() and + ( + sink.getNode().(ComputationallyExpensiveHashFunction::Sink).isComputationallyExpensive() and + ending = "." + or + not sink.getNode().(ComputationallyExpensiveHashFunction::Sink).isComputationallyExpensive() and + ending = + " for " + classification + + " hashing, since it is not a computationally expensive hash function." + ) ) select sink.getNode(), source, sink, "$@ is used in a hashing algorithm (" + algorithmName + ") that is insecure" + ending, diff --git a/python/ql/src/Security/CWE-502/UnsafeDeserialization.ql b/python/ql/src/Security/CWE-502/UnsafeDeserialization.ql index 395101de78f..a15838cdabd 100644 --- a/python/ql/src/Security/CWE-502/UnsafeDeserialization.ql +++ b/python/ql/src/Security/CWE-502/UnsafeDeserialization.ql @@ -14,9 +14,9 @@ import python import semmle.python.security.dataflow.UnsafeDeserializationQuery -import UnsafeDeserializationFlow::PathGraph +import DataFlow::PathGraph -from UnsafeDeserializationFlow::PathNode source, UnsafeDeserializationFlow::PathNode sink -where UnsafeDeserializationFlow::flowPath(source, sink) +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Unsafe deserialization depends on a $@.", source.getNode(), "user-provided value" diff --git a/python/ql/src/Security/CWE-601/UrlRedirect.ql b/python/ql/src/Security/CWE-601/UrlRedirect.ql index 813cb4a997a..fbe3f3349ce 100644 --- a/python/ql/src/Security/CWE-601/UrlRedirect.ql +++ b/python/ql/src/Security/CWE-601/UrlRedirect.ql @@ -14,9 +14,9 @@ import python import semmle.python.security.dataflow.UrlRedirectQuery -import UrlRedirectFlow::PathGraph +import DataFlow::PathGraph -from UrlRedirectFlow::PathNode source, UrlRedirectFlow::PathNode sink -where UrlRedirectFlow::flowPath(source, sink) +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Untrusted URL redirection depends on a $@.", source.getNode(), "user-provided value" diff --git a/python/ql/src/Security/CWE-611/Xxe.ql b/python/ql/src/Security/CWE-611/Xxe.ql index 948e0f8a5f9..b361f6ffcfb 100644 --- a/python/ql/src/Security/CWE-611/Xxe.ql +++ b/python/ql/src/Security/CWE-611/Xxe.ql @@ -14,10 +14,10 @@ import python import semmle.python.security.dataflow.XxeQuery -import XxeFlow::PathGraph +import DataFlow::PathGraph -from XxeFlow::PathNode source, XxeFlow::PathNode sink -where XxeFlow::flowPath(source, sink) +from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink +where cfg.hasFlowPath(source, sink) select sink.getNode(), source, sink, "XML parsing depends on a $@ without guarding against external entity expansion.", source.getNode(), "user-provided value" diff --git a/python/ql/src/Security/CWE-643/XpathInjection.ql b/python/ql/src/Security/CWE-643/XpathInjection.ql index 90d4bcbd2c3..07df47624e7 100644 --- a/python/ql/src/Security/CWE-643/XpathInjection.ql +++ b/python/ql/src/Security/CWE-643/XpathInjection.ql @@ -13,9 +13,9 @@ import python import semmle.python.security.dataflow.XpathInjectionQuery -import XpathInjectionFlow::PathGraph +import DataFlow::PathGraph -from XpathInjectionFlow::PathNode source, XpathInjectionFlow::PathNode sink -where XpathInjectionFlow::flowPath(source, sink) +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "XPath expression depends on a $@.", source.getNode(), "user-provided value" diff --git a/python/ql/src/Security/CWE-730/PolynomialReDoS.ql b/python/ql/src/Security/CWE-730/PolynomialReDoS.ql index b3b4a8cac92..1b315c651c3 100644 --- a/python/ql/src/Security/CWE-730/PolynomialReDoS.ql +++ b/python/ql/src/Security/CWE-730/PolynomialReDoS.ql @@ -15,13 +15,13 @@ import python import semmle.python.security.dataflow.PolynomialReDoSQuery -import PolynomialReDoSFlow::PathGraph +import DataFlow::PathGraph from - PolynomialReDoSFlow::PathNode source, PolynomialReDoSFlow::PathNode sink, Sink sinkNode, + Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink, Sink sinkNode, PolynomialBackTrackingTerm regexp where - PolynomialReDoSFlow::flowPath(source, sink) and + config.hasFlowPath(source, sink) and sinkNode = sink.getNode() and regexp.getRootTerm() = sinkNode.getRegExp() // not ( diff --git a/python/ql/src/Security/CWE-730/RegexInjection.ql b/python/ql/src/Security/CWE-730/RegexInjection.ql index fe1dc1dfe66..5075c7a675d 100644 --- a/python/ql/src/Security/CWE-730/RegexInjection.ql +++ b/python/ql/src/Security/CWE-730/RegexInjection.ql @@ -16,13 +16,13 @@ import python private import semmle.python.Concepts import semmle.python.security.dataflow.RegexInjectionQuery -import RegexInjectionFlow::PathGraph +import DataFlow::PathGraph from - RegexInjectionFlow::PathNode source, RegexInjectionFlow::PathNode sink, + Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink, RegexExecution regexExecution where - RegexInjectionFlow::flowPath(source, sink) and + config.hasFlowPath(source, sink) and regexExecution = sink.getNode().(Sink).getRegexExecution() select sink.getNode(), source, sink, "This regular expression depends on a $@ and is executed by $@.", source.getNode(), diff --git a/python/ql/src/Security/CWE-776/XmlBomb.ql b/python/ql/src/Security/CWE-776/XmlBomb.ql index c92d4f289f5..f943aa58c44 100644 --- a/python/ql/src/Security/CWE-776/XmlBomb.ql +++ b/python/ql/src/Security/CWE-776/XmlBomb.ql @@ -14,10 +14,10 @@ import python import semmle.python.security.dataflow.XmlBombQuery -import XmlBombFlow::PathGraph +import DataFlow::PathGraph -from XmlBombFlow::PathNode source, XmlBombFlow::PathNode sink -where XmlBombFlow::flowPath(source, sink) +from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink +where cfg.hasFlowPath(source, sink) select sink.getNode(), source, sink, "XML parsing depends on a $@ without guarding against uncontrolled entity expansion.", source.getNode(), "user-provided value" diff --git a/python/ql/src/Security/CWE-798/HardcodedCredentials.ql b/python/ql/src/Security/CWE-798/HardcodedCredentials.ql index 0a92427ec23..d1d29a78ff5 100644 --- a/python/ql/src/Security/CWE-798/HardcodedCredentials.ql +++ b/python/ql/src/Security/CWE-798/HardcodedCredentials.ql @@ -16,6 +16,7 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import semmle.python.filters.Tests +import DataFlow::PathGraph bindingset[char, fraction] predicate fewer_characters_than(StrConst str, string char, float fraction) { @@ -107,19 +108,17 @@ private string getACredentialRegex() { result = "(?i).*(cert)(?!.*(format|name)).*" } -private module HardcodedCredentialsConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof HardcodedValueSource } +class HardcodedCredentialsConfiguration extends TaintTracking::Configuration { + HardcodedCredentialsConfiguration() { this = "Hardcoded credentials configuration" } - predicate isSink(DataFlow::Node sink) { sink instanceof CredentialSink } + override predicate isSource(DataFlow::Node source) { source instanceof HardcodedValueSource } + + override predicate isSink(DataFlow::Node sink) { sink instanceof CredentialSink } } -module HardcodedCredentialsFlow = TaintTracking::Global; - -import HardcodedCredentialsFlow::PathGraph - -from HardcodedCredentialsFlow::PathNode src, HardcodedCredentialsFlow::PathNode sink +from HardcodedCredentialsConfiguration config, DataFlow::PathNode src, DataFlow::PathNode sink where - HardcodedCredentialsFlow::flowPath(src, sink) and + config.hasFlowPath(src, sink) and not any(TestScope test).contains(src.getNode().asCfgNode().getNode()) select src.getNode(), src, sink, "This hardcoded value is $@.", sink.getNode(), "used as credentials" diff --git a/python/ql/src/Security/CWE-918/FullServerSideRequestForgery.ql b/python/ql/src/Security/CWE-918/FullServerSideRequestForgery.ql index 4114ff31ce0..a29f9e775a1 100644 --- a/python/ql/src/Security/CWE-918/FullServerSideRequestForgery.ql +++ b/python/ql/src/Security/CWE-918/FullServerSideRequestForgery.ql @@ -12,14 +12,14 @@ import python import semmle.python.security.dataflow.ServerSideRequestForgeryQuery -import FullServerSideRequestForgeryFlow::PathGraph +import DataFlow::PathGraph from - FullServerSideRequestForgeryFlow::PathNode source, - FullServerSideRequestForgeryFlow::PathNode sink, Http::Client::Request request + FullServerSideRequestForgeryConfiguration fullConfig, DataFlow::PathNode source, + DataFlow::PathNode sink, Http::Client::Request request where request = sink.getNode().(Sink).getRequest() and - FullServerSideRequestForgeryFlow::flowPath(source, sink) and + fullConfig.hasFlowPath(source, sink) and fullyControlledRequest(request) select request, source, sink, "The full URL of this request depends on a $@.", source.getNode(), "user-provided value" diff --git a/python/ql/src/Security/CWE-918/PartialServerSideRequestForgery.ql b/python/ql/src/Security/CWE-918/PartialServerSideRequestForgery.ql index c6c679ca5e3..3bbeaabcce6 100644 --- a/python/ql/src/Security/CWE-918/PartialServerSideRequestForgery.ql +++ b/python/ql/src/Security/CWE-918/PartialServerSideRequestForgery.ql @@ -12,14 +12,14 @@ import python import semmle.python.security.dataflow.ServerSideRequestForgeryQuery -import PartialServerSideRequestForgeryFlow::PathGraph +import DataFlow::PathGraph from - PartialServerSideRequestForgeryFlow::PathNode source, - PartialServerSideRequestForgeryFlow::PathNode sink, Http::Client::Request request + PartialServerSideRequestForgeryConfiguration partialConfig, DataFlow::PathNode source, + DataFlow::PathNode sink, Http::Client::Request request where request = sink.getNode().(Sink).getRequest() and - PartialServerSideRequestForgeryFlow::flowPath(source, sink) and + partialConfig.hasFlowPath(source, sink) and not fullyControlledRequest(request) select request, source, sink, "Part of the URL of this request depends on a $@.", source.getNode(), "user-provided value" diff --git a/python/ql/src/experimental/Security/CWE-022/ZipSlip.ql b/python/ql/src/experimental/Security/CWE-022/ZipSlip.ql index 4bdca63e1d6..eba8da087b3 100644 --- a/python/ql/src/experimental/Security/CWE-022/ZipSlip.ql +++ b/python/ql/src/experimental/Security/CWE-022/ZipSlip.ql @@ -15,10 +15,10 @@ import python import experimental.semmle.python.security.ZipSlip -import ZipSlipFlow::PathGraph +import DataFlow::PathGraph -from ZipSlipFlow::PathNode source, ZipSlipFlow::PathNode sink -where ZipSlipFlow::flowPath(source, sink) +from ZipSlipConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select source.getNode(), source, sink, "This unsanitized archive entry, which may contain '..', is used in a $@.", sink.getNode(), "file system operation" diff --git a/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql b/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql index 431fe293cec..65ff272bbbd 100755 --- a/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql +++ b/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql @@ -16,7 +16,7 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking -import TarSlipImprovFlow::PathGraph +import DataFlow::PathGraph import semmle.python.ApiGraphs import semmle.python.dataflow.new.internal.Attributes import semmle.python.dataflow.new.BarrierGuards @@ -54,10 +54,12 @@ class AllTarfileOpens extends API::CallNode { /** * A taint-tracking configuration for detecting more "TarSlip" vulnerabilities. */ -private module TarSlipImprovConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source = tarfileOpen().getACall() } +class Configuration extends TaintTracking::Configuration { + Configuration() { this = "TarSlip" } - predicate isSink(DataFlow::Node sink) { + override predicate isSource(DataFlow::Node source) { source = tarfileOpen().getACall() } + + override predicate isSink(DataFlow::Node sink) { ( // A sink capturing method calls to `extractall` without `members` argument. // For a call to `file.extractall` without `members` argument, `file` is considered a sink. @@ -98,7 +100,7 @@ private module TarSlipImprovConfig implements DataFlow::ConfigSig { not sink.getScope().getLocation().getFile().inStdlib() } - predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { nodeTo.(MethodCallNode).calls(nodeFrom, "getmembers") and nodeFrom instanceof AllTarfileOpens or @@ -111,10 +113,7 @@ private module TarSlipImprovConfig implements DataFlow::ConfigSig { } } -/** Global taint-tracking for detecting more "TarSlip" vulnerabilities. */ -module TarSlipImprovFlow = TaintTracking::Global; - -from TarSlipImprovFlow::PathNode source, TarSlipImprovFlow::PathNode sink -where TarSlipImprovFlow::flowPath(source, sink) +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink, source, sink, "Extraction of tarfile from $@ to a potentially untrusted source $@.", source.getNode(), source.getNode().toString(), sink.getNode(), sink.getNode().toString() diff --git a/python/ql/src/experimental/Security/CWE-022bis/UnsafeUnpack.ql b/python/ql/src/experimental/Security/CWE-022bis/UnsafeUnpack.ql index 1afe3f738ad..a6a0e06559c 100644 --- a/python/ql/src/experimental/Security/CWE-022bis/UnsafeUnpack.ql +++ b/python/ql/src/experimental/Security/CWE-022bis/UnsafeUnpack.ql @@ -16,9 +16,9 @@ import python import experimental.Security.UnsafeUnpackQuery -import UnsafeUnpackFlow::PathGraph +import DataFlow::PathGraph -from UnsafeUnpackFlow::PathNode source, UnsafeUnpackFlow::PathNode sink -where UnsafeUnpackFlow::flowPath(source, sink) +from UnsafeUnpackingConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Unsafe extraction from a malicious tarball retrieved from a remote location." diff --git a/python/ql/src/experimental/Security/CWE-074/paramiko/paramiko.ql b/python/ql/src/experimental/Security/CWE-074/paramiko/paramiko.ql index a902ff045c4..5a38a673080 100644 --- a/python/ql/src/experimental/Security/CWE-074/paramiko/paramiko.ql +++ b/python/ql/src/experimental/Security/CWE-074/paramiko/paramiko.ql @@ -16,13 +16,16 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import semmle.python.dataflow.new.RemoteFlowSources import semmle.python.ApiGraphs +import DataFlow::PathGraph private API::Node paramikoClient() { result = API::moduleImport("paramiko").getMember("SSHClient").getReturn() } -private module ParamikoConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } +class ParamikoCmdInjectionConfiguration extends TaintTracking::Configuration { + ParamikoCmdInjectionConfiguration() { this = "ParamikoCMDInjectionConfiguration" } + + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } /** * exec_command of `paramiko.SSHClient` class execute command on ssh target server @@ -30,7 +33,7 @@ private module ParamikoConfig implements DataFlow::ConfigSig { * and it run CMD on current system that running the ssh command * the Sink related to proxy command is the `connect` method of `paramiko.SSHClient` class */ - predicate isSink(DataFlow::Node sink) { + override predicate isSink(DataFlow::Node sink) { sink = paramikoClient().getMember("exec_command").getACall().getParameter(0, "command").asSink() or sink = paramikoClient().getMember("connect").getACall().getParameter(11, "sock").asSink() @@ -39,7 +42,7 @@ private module ParamikoConfig implements DataFlow::ConfigSig { /** * this additional taint step help taint tracking to find the vulnerable `connect` method of `paramiko.SSHClient` class */ - predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { exists(API::CallNode call | call = API::moduleImport("paramiko").getMember("ProxyCommand").getACall() and nodeFrom = call.getParameter(0, "command_line").asSink() and @@ -48,12 +51,7 @@ private module ParamikoConfig implements DataFlow::ConfigSig { } } -/** Global taint-tracking for detecting "paramiko command injection" vulnerabilities. */ -module ParamikoFlow = TaintTracking::Global; - -import ParamikoFlow::PathGraph - -from ParamikoFlow::PathNode source, ParamikoFlow::PathNode sink -where ParamikoFlow::flowPath(source, sink) +from ParamikoCmdInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "This code execution depends on a $@.", source.getNode(), "a user-provided value" diff --git a/python/ql/src/experimental/Security/CWE-079/EmailXss.ql b/python/ql/src/experimental/Security/CWE-079/ReflectedXSS.ql similarity index 72% rename from python/ql/src/experimental/Security/CWE-079/EmailXss.ql rename to python/ql/src/experimental/Security/CWE-079/ReflectedXSS.ql index 046efdeba89..468cef01f7d 100644 --- a/python/ql/src/experimental/Security/CWE-079/EmailXss.ql +++ b/python/ql/src/experimental/Security/CWE-079/ReflectedXSS.ql @@ -15,10 +15,10 @@ // determine precision above import python -import experimental.semmle.python.security.dataflow.EmailXss -import EmailXssFlow::PathGraph +import experimental.semmle.python.security.dataflow.ReflectedXSS +import DataFlow::PathGraph -from EmailXssFlow::PathNode source, EmailXssFlow::PathNode sink -where EmailXssFlow::flowPath(source, sink) +from ReflectedXssConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Cross-site scripting vulnerability due to $@.", source.getNode(), "a user-provided value" diff --git a/python/ql/src/experimental/Security/CWE-113/HeaderInjection.ql b/python/ql/src/experimental/Security/CWE-113/HeaderInjection.ql index 6527df03339..65305d2f3b5 100644 --- a/python/ql/src/experimental/Security/CWE-113/HeaderInjection.ql +++ b/python/ql/src/experimental/Security/CWE-113/HeaderInjection.ql @@ -14,9 +14,9 @@ // determine precision above import python import experimental.semmle.python.security.injection.HTTPHeaders -import HeaderInjectionFlow::PathGraph +import DataFlow::PathGraph -from HeaderInjectionFlow::PathNode source, HeaderInjectionFlow::PathNode sink -where HeaderInjectionFlow::flowPath(source, sink) +from HeaderInjectionFlowConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "This HTTP header is constructed from a $@.", source.getNode(), "user-provided value" diff --git a/python/ql/src/experimental/Security/CWE-1236/CsvInjection.ql b/python/ql/src/experimental/Security/CWE-1236/CsvInjection.ql index df9b7cf9f65..28a68dd78df 100644 --- a/python/ql/src/experimental/Security/CWE-1236/CsvInjection.ql +++ b/python/ql/src/experimental/Security/CWE-1236/CsvInjection.ql @@ -11,11 +11,11 @@ */ import python -import CsvInjectionFlow::PathGraph +import DataFlow::PathGraph import semmle.python.dataflow.new.DataFlow import experimental.semmle.python.security.injection.CsvInjection -from CsvInjectionFlow::PathNode source, CsvInjectionFlow::PathNode sink -where CsvInjectionFlow::flowPath(source, sink) +from CsvInjectionFlowConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Csv injection might include code from $@.", source.getNode(), "this user input" diff --git a/python/ql/src/experimental/Security/CWE-176/UnicodeBypassValidation.ql b/python/ql/src/experimental/Security/CWE-176/UnicodeBypassValidation.ql index f830c0ea25d..67c61653763 100644 --- a/python/ql/src/experimental/Security/CWE-176/UnicodeBypassValidation.ql +++ b/python/ql/src/experimental/Security/CWE-176/UnicodeBypassValidation.ql @@ -14,10 +14,10 @@ import python import UnicodeBypassValidationQuery -import UnicodeBypassValidationFlow::PathGraph +import DataFlow::PathGraph -from UnicodeBypassValidationFlow::PathNode source, UnicodeBypassValidationFlow::PathNode sink -where UnicodeBypassValidationFlow::flowPath(source, sink) +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "This $@ processes unsafely $@ and any logical validation in-between could be bypassed using special Unicode characters.", sink.getNode(), "Unicode transformation (Unicode normalization)", source.getNode(), diff --git a/python/ql/src/experimental/Security/CWE-176/UnicodeBypassValidationQuery.qll b/python/ql/src/experimental/Security/CWE-176/UnicodeBypassValidationQuery.qll index a5d9d53b084..702a69a7095 100644 --- a/python/ql/src/experimental/Security/CWE-176/UnicodeBypassValidationQuery.qll +++ b/python/ql/src/experimental/Security/CWE-176/UnicodeBypassValidationQuery.qll @@ -3,7 +3,6 @@ */ private import python -import semmle.python.dataflow.new.DataFlow import semmle.python.ApiGraphs import semmle.python.Concepts import semmle.python.dataflow.new.internal.DataFlowPublic @@ -28,15 +27,16 @@ class PostValidation extends DataFlow::FlowState { * This configuration uses two flow states, `PreValidation` and `PostValidation`, * to track the requirement that a logical validation has been performed before the Unicode Transformation. */ -private module UnicodeBypassValidationConfig implements DataFlow::StateConfigSig { - class FlowState = DataFlow::FlowState; +class Configuration extends TaintTracking::Configuration { + Configuration() { this = "UnicodeBypassValidation" } - predicate isSource(DataFlow::Node source, FlowState state) { + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { source instanceof RemoteFlowSource and state instanceof PreValidation } - predicate isAdditionalFlowStep( - DataFlow::Node nodeFrom, FlowState stateFrom, DataFlow::Node nodeTo, FlowState stateTo + override predicate isAdditionalTaintStep( + DataFlow::Node nodeFrom, DataFlow::FlowState stateFrom, DataFlow::Node nodeTo, + DataFlow::FlowState stateTo ) { ( exists(Escaping escaping | nodeFrom = escaping.getAnInput() and nodeTo = escaping.getOutput()) @@ -51,7 +51,7 @@ private module UnicodeBypassValidationConfig implements DataFlow::StateConfigSig } /* A Unicode Tranformation (Unicode tranformation) is considered a sink when the algorithm used is either NFC or NFKC. */ - predicate isSink(DataFlow::Node sink, FlowState state) { + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { exists(API::CallNode cn | cn = API::moduleImport("unicodedata").getMember("normalize").getACall() and sink = cn.getArg(1) @@ -71,6 +71,3 @@ private module UnicodeBypassValidationConfig implements DataFlow::StateConfigSig state instanceof PostValidation } } - -/** Global taint-tracking for detecting "Unicode transformation mishandling" vulnerabilities. */ -module UnicodeBypassValidationFlow = TaintTracking::GlobalWithState; diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql index 82ba11c1d4b..f46b93fb266 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql @@ -17,25 +17,21 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import experimental.semmle.python.security.TimingAttack +import DataFlow::PathGraph /** * A configuration that tracks data flow from cryptographic operations * to equality test */ -private module PossibleTimingAttackAgainstHashConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof ProduceCryptoCall } +class PossibleTimingAttackAgainstHash extends TaintTracking::Configuration { + PossibleTimingAttackAgainstHash() { this = "PossibleTimingAttackAgainstHash" } - predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink } + override predicate isSource(DataFlow::Node source) { source instanceof ProduceCryptoCall } + + override predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink } } -module PossibleTimingAttackAgainstHashFlow = - TaintTracking::Global; - -import PossibleTimingAttackAgainstHashFlow::PathGraph - -from - PossibleTimingAttackAgainstHashFlow::PathNode source, - PossibleTimingAttackAgainstHashFlow::PathNode sink -where PossibleTimingAttackAgainstHashFlow::flowPath(source, sink) +from PossibleTimingAttackAgainstHash config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Possible Timing attack against $@ validation.", source.getNode().(ProduceCryptoCall).getResultType(), "message" diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql index e08f1dbb517..392356b7c42 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql @@ -16,24 +16,23 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import experimental.semmle.python.security.TimingAttack +import DataFlow::PathGraph /** * A configuration that tracks data flow from cryptographic operations * to Equality test. */ -private module TimingAttackAgainstHashConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof ProduceCryptoCall } +class TimingAttackAgainsthash extends TaintTracking::Configuration { + TimingAttackAgainsthash() { this = "TimingAttackAgainsthash" } - predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink } + override predicate isSource(DataFlow::Node source) { source instanceof ProduceCryptoCall } + + override predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink } } -module TimingAttackAgainstHashFlow = TaintTracking::Global; - -import TimingAttackAgainstHashFlow::PathGraph - -from TimingAttackAgainstHashFlow::PathNode source, TimingAttackAgainstHashFlow::PathNode sink +from TimingAttackAgainsthash config, DataFlow::PathNode source, DataFlow::PathNode sink where - TimingAttackAgainstHashFlow::flowPath(source, sink) and + config.hasFlowPath(source, sink) and sink.getNode().(NonConstantTimeComparisonSink).includesUserInput() select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode().(ProduceCryptoCall).getResultType(), "message" diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql index a1da41530a8..1f2ff8f50fb 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql @@ -15,26 +15,20 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import experimental.semmle.python.security.TimingAttack +import DataFlow::PathGraph /** * A configuration tracing flow from a client Secret obtained by an HTTP header to a unsafe Comparison. */ -private module TimingAttackAgainstHeaderValueConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof ClientSuppliedSecret } +class ClientSuppliedSecretConfig extends TaintTracking::Configuration { + ClientSuppliedSecretConfig() { this = "ClientSuppliedSecretConfig" } - predicate isSink(DataFlow::Node sink) { sink instanceof CompareSink } + override predicate isSource(DataFlow::Node source) { source instanceof ClientSuppliedSecret } + + override predicate isSink(DataFlow::Node sink) { sink instanceof CompareSink } } -module TimingAttackAgainstHeaderValueFlow = - TaintTracking::Global; - -import TimingAttackAgainstHeaderValueFlow::PathGraph - -from - TimingAttackAgainstHeaderValueFlow::PathNode source, - TimingAttackAgainstHeaderValueFlow::PathNode sink -where - TimingAttackAgainstHeaderValueFlow::flowPath(source, sink) and - not sink.getNode().(CompareSink).flowtolen() +from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) and not sink.getNode().(CompareSink).flowtolen() select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), "client-supplied token" diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql index cdf350dd7cd..d43c3aa8995 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql @@ -15,24 +15,20 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import experimental.semmle.python.security.TimingAttack +import DataFlow::PathGraph /** * A configuration tracing flow from obtaining a client Secret to a unsafe Comparison. */ -private module PossibleTimingAttackAgainstSensitiveInfoConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof SecretSource } +class ClientSuppliedSecretConfig extends TaintTracking::Configuration { + ClientSuppliedSecretConfig() { this = "ClientSuppliedSecretConfig" } - predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink } + override predicate isSource(DataFlow::Node source) { source instanceof SecretSource } + + override predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink } } -module PossibleTimingAttackAgainstSensitiveInfoFlow = - TaintTracking::Global; - -import PossibleTimingAttackAgainstSensitiveInfoFlow::PathGraph - -from - PossibleTimingAttackAgainstSensitiveInfoFlow::PathNode source, - PossibleTimingAttackAgainstSensitiveInfoFlow::PathNode sink -where PossibleTimingAttackAgainstSensitiveInfoFlow::flowPath(source, sink) +from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), "client-supplied token" diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql index 8ec4fac97e3..63587d4afcc 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql @@ -15,25 +15,22 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import experimental.semmle.python.security.TimingAttack -import TimingAttackAgainstSensitiveInfoFlow::PathGraph +import DataFlow::PathGraph /** * A configuration tracing flow from obtaining a client Secret to a unsafe Comparison. */ -private module TimingAttackAgainstSensitiveInfoConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof SecretSource } +class ClientSuppliedSecretConfig extends TaintTracking::Configuration { + ClientSuppliedSecretConfig() { this = "ClientSuppliedSecretConfig" } - predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink } + override predicate isSource(DataFlow::Node source) { source instanceof SecretSource } + + override predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink } } -module TimingAttackAgainstSensitiveInfoFlow = - TaintTracking::Global; - -from - TimingAttackAgainstSensitiveInfoFlow::PathNode source, - TimingAttackAgainstSensitiveInfoFlow::PathNode sink +from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::PathNode sink where - TimingAttackAgainstSensitiveInfoFlow::flowPath(source, sink) and + config.hasFlowPath(source, sink) and ( source.getNode().(SecretSource).includesUserInput() or sink.getNode().(NonConstantTimeComparisonSink).includesUserInput() diff --git a/python/ql/src/experimental/Security/CWE-287-ConstantSecretKey/WebAppConstantSecretKey.ql b/python/ql/src/experimental/Security/CWE-287-ConstantSecretKey/WebAppConstantSecretKey.ql index 7bb35012b38..38548628237 100644 --- a/python/ql/src/experimental/Security/CWE-287-ConstantSecretKey/WebAppConstantSecretKey.ql +++ b/python/ql/src/experimental/Security/CWE-287-ConstantSecretKey/WebAppConstantSecretKey.ql @@ -25,7 +25,7 @@ newtype TFrameWork = Flask() or Django() -private module WebAppConstantSecretKeyConfig implements DataFlow::StateConfigSig { +module WebAppConstantSecretKeyConfig implements DataFlow::StateConfigSig { class FlowState = TFrameWork; predicate isSource(DataFlow::Node source, FlowState state) { @@ -54,11 +54,11 @@ private module WebAppConstantSecretKeyConfig implements DataFlow::StateConfigSig } } -module WebAppConstantSecretKeyFlow = TaintTracking::GlobalWithState; +module WebAppConstantSecretKey = TaintTracking::GlobalWithState; -import WebAppConstantSecretKeyFlow::PathGraph +import WebAppConstantSecretKey::PathGraph -from WebAppConstantSecretKeyFlow::PathNode source, WebAppConstantSecretKeyFlow::PathNode sink -where WebAppConstantSecretKeyFlow::flowPath(source, sink) +from WebAppConstantSecretKey::PathNode source, WebAppConstantSecretKey::PathNode sink +where WebAppConstantSecretKey::flowPath(source, sink) select sink, source, sink, "The SECRET_KEY config variable is assigned by $@.", source, " this constant String" diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index b23ca4b0bc6..9b73cdcec87 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -96,7 +96,7 @@ newtype TAzureFlowState = MkUsesV1Encryption() or MkUsesNoEncryption() -private module AzureBlobClientConfig implements DataFlow::StateConfigSig { +module AzureBlobClientConfig implements DataFlow::StateConfigSig { class FlowState = TAzureFlowState; predicate isSource(DataFlow::Node node, FlowState state) { @@ -147,10 +147,10 @@ private module AzureBlobClientConfig implements DataFlow::StateConfigSig { } } -module AzureBlobClientFlow = DataFlow::GlobalWithState; +module AzureBlobClient = DataFlow::GlobalWithState; -import AzureBlobClientFlow::PathGraph +import AzureBlobClient::PathGraph -from AzureBlobClientFlow::PathNode source, AzureBlobClientFlow::PathNode sink -where AzureBlobClientFlow::flowPath(source, sink) +from AzureBlobClient::PathNode source, AzureBlobClient::PathNode sink +where AzureBlobClient::flowPath(source, sink) select sink, source, sink, "Unsafe usage of v1 version of Azure Storage client-side encryption" diff --git a/python/ql/src/experimental/Security/CWE-338/InsecureRandomness.ql b/python/ql/src/experimental/Security/CWE-338/InsecureRandomness.ql index 1991300726b..476906283aa 100644 --- a/python/ql/src/experimental/Security/CWE-338/InsecureRandomness.ql +++ b/python/ql/src/experimental/Security/CWE-338/InsecureRandomness.ql @@ -14,11 +14,11 @@ */ import python -import experimental.semmle.python.security.InsecureRandomness +import experimental.semmle.python.security.InsecureRandomness::InsecureRandomness import semmle.python.dataflow.new.DataFlow -import InsecureRandomness::Flow::PathGraph +import DataFlow::PathGraph -from InsecureRandomness::Flow::PathNode source, InsecureRandomness::Flow::PathNode sink -where InsecureRandomness::Flow::flowPath(source, sink) +from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink +where cfg.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Cryptographically insecure $@ in a security context.", source.getNode(), "random value" diff --git a/python/ql/src/experimental/Security/CWE-340/TokenBuiltFromUUID.ql b/python/ql/src/experimental/Security/CWE-340/TokenBuiltFromUUID.ql index b91f2dd6237..711abdb2f33 100644 --- a/python/ql/src/experimental/Security/CWE-340/TokenBuiltFromUUID.ql +++ b/python/ql/src/experimental/Security/CWE-340/TokenBuiltFromUUID.ql @@ -16,6 +16,7 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.ApiGraphs import semmle.python.dataflow.new.TaintTracking +import DataFlow::PathGraph class PredictableResultSource extends DataFlow::Node { PredictableResultSource() { @@ -39,12 +40,14 @@ class TokenAssignmentValueSink extends DataFlow::Node { } } -private module TokenBuiltFromUuidConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof PredictableResultSource } +class TokenBuiltFromUuidConfig extends TaintTracking::Configuration { + TokenBuiltFromUuidConfig() { this = "TokenBuiltFromUuidConfig" } - predicate isSink(DataFlow::Node sink) { sink instanceof TokenAssignmentValueSink } + override predicate isSource(DataFlow::Node source) { source instanceof PredictableResultSource } - predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + override predicate isSink(DataFlow::Node sink) { sink instanceof TokenAssignmentValueSink } + + override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { exists(DataFlow::CallCfgNode call | call = API::builtin("str").getACall() and nodeFrom = call.getArg(0) and @@ -53,11 +56,6 @@ private module TokenBuiltFromUuidConfig implements DataFlow::ConfigSig { } } -/** Global taint-tracking for detecting "TokenBuiltFromUUID" vulnerabilities. */ -module TokenBuiltFromUuidFlow = TaintTracking::Global; - -import TokenBuiltFromUuidFlow::PathGraph - -from TokenBuiltFromUuidFlow::PathNode source, TokenBuiltFromUuidFlow::PathNode sink -where TokenBuiltFromUuidFlow::flowPath(source, sink) +from DataFlow::PathNode source, DataFlow::PathNode sink, TokenBuiltFromUuidConfig config +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Token built from $@.", source.getNode(), "predictable value" diff --git a/python/ql/src/experimental/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.ql b/python/ql/src/experimental/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.ql index 51d6c9b6652..aec637269ac 100644 --- a/python/ql/src/experimental/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.ql +++ b/python/ql/src/experimental/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.ql @@ -16,19 +16,21 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import semmle.python.ApiGraphs import ClientSuppliedIpUsedInSecurityCheckLib -import ClientSuppliedIpUsedInSecurityCheckFlow::PathGraph +import DataFlow::PathGraph /** * A taint-tracking configuration tracing flow from obtaining a client ip from an HTTP header to a sensitive use. */ -private module ClientSuppliedIpUsedInSecurityCheckConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { +class ClientSuppliedIpUsedInSecurityCheckConfig extends TaintTracking::Configuration { + ClientSuppliedIpUsedInSecurityCheckConfig() { this = "ClientSuppliedIpUsedInSecurityCheckConfig" } + + override predicate isSource(DataFlow::Node source) { source instanceof ClientSuppliedIpUsedInSecurityCheck } - predicate isSink(DataFlow::Node sink) { sink instanceof PossibleSecurityCheck } + override predicate isSink(DataFlow::Node sink) { sink instanceof PossibleSecurityCheck } - predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { + override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { exists(DataFlow::CallCfgNode ccn | ccn = API::moduleImport("netaddr").getMember("IPAddress").getACall() and ccn.getArg(0) = pred and @@ -36,7 +38,7 @@ private module ClientSuppliedIpUsedInSecurityCheckConfig implements DataFlow::Co ) } - predicate isBarrier(DataFlow::Node node) { + override predicate isSanitizer(DataFlow::Node node) { // `client_supplied_ip.split(",")[n]` for `n` > 0 exists(Subscript ss | not ss.getIndex().(IntegerLiteral).getText() = "0" and @@ -47,13 +49,9 @@ private module ClientSuppliedIpUsedInSecurityCheckConfig implements DataFlow::Co } } -/** Global taint-tracking for detecting "client ip used in security check" vulnerabilities. */ -module ClientSuppliedIpUsedInSecurityCheckFlow = - TaintTracking::Global; - from - ClientSuppliedIpUsedInSecurityCheckFlow::PathNode source, - ClientSuppliedIpUsedInSecurityCheckFlow::PathNode sink -where ClientSuppliedIpUsedInSecurityCheckFlow::flowPath(source, sink) + ClientSuppliedIpUsedInSecurityCheckConfig config, DataFlow::PathNode source, + DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "IP address spoofing might include code from $@.", source.getNode(), "this user input" diff --git a/python/ql/src/experimental/Security/CWE-522/LdapInsecureAuth.qhelp b/python/ql/src/experimental/Security/CWE-522/LDAPInsecureAuth.qhelp similarity index 100% rename from python/ql/src/experimental/Security/CWE-522/LdapInsecureAuth.qhelp rename to python/ql/src/experimental/Security/CWE-522/LDAPInsecureAuth.qhelp diff --git a/python/ql/src/experimental/Security/CWE-522/LdapInsecureAuth.ql b/python/ql/src/experimental/Security/CWE-522/LDAPInsecureAuth.ql similarity index 64% rename from python/ql/src/experimental/Security/CWE-522/LdapInsecureAuth.ql rename to python/ql/src/experimental/Security/CWE-522/LDAPInsecureAuth.ql index 8b72780d91a..960ef9a671a 100644 --- a/python/ql/src/experimental/Security/CWE-522/LdapInsecureAuth.ql +++ b/python/ql/src/experimental/Security/CWE-522/LDAPInsecureAuth.ql @@ -12,9 +12,9 @@ // determine precision above import python -import experimental.semmle.python.security.LdapInsecureAuth -import LdapInsecureAuthFlow::PathGraph +import DataFlow::PathGraph +import experimental.semmle.python.security.LDAPInsecureAuth -from LdapInsecureAuthFlow::PathNode source, LdapInsecureAuthFlow::PathNode sink -where LdapInsecureAuthFlow::flowPath(source, sink) +from LdapInsecureAuthConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "This LDAP host is authenticated insecurely." diff --git a/python/ql/src/experimental/Security/CWE-614/CookieInjection.ql b/python/ql/src/experimental/Security/CWE-614/CookieInjection.ql index 4193e37dee2..894a69753d9 100644 --- a/python/ql/src/experimental/Security/CWE-614/CookieInjection.ql +++ b/python/ql/src/experimental/Security/CWE-614/CookieInjection.ql @@ -15,11 +15,13 @@ import semmle.python.dataflow.new.DataFlow import experimental.semmle.python.Concepts import experimental.semmle.python.CookieHeader import experimental.semmle.python.security.injection.CookieInjection -import CookieInjectionFlow::PathGraph +import DataFlow::PathGraph -from CookieInjectionFlow::PathNode source, CookieInjectionFlow::PathNode sink, string insecure +from + CookieInjectionFlowConfig config, DataFlow::PathNode source, DataFlow::PathNode sink, + string insecure where - CookieInjectionFlow::flowPath(source, sink) and + config.hasFlowPath(source, sink) and if exists(sink.getNode().(CookieSink)) then insecure = ",and its " + sink.getNode().(CookieSink).getFlag() + " flag is not properly set." else insecure = "." diff --git a/python/ql/src/experimental/Security/UnsafeUnpackQuery.qll b/python/ql/src/experimental/Security/UnsafeUnpackQuery.qll index 338a5555c57..ba359ee32f3 100644 --- a/python/ql/src/experimental/Security/UnsafeUnpackQuery.qll +++ b/python/ql/src/experimental/Security/UnsafeUnpackQuery.qll @@ -39,8 +39,10 @@ class AllTarfileOpens extends API::CallNode { } } -module UnsafeUnpackConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { +class UnsafeUnpackingConfig extends TaintTracking::Configuration { + UnsafeUnpackingConfig() { this = "UnsafeUnpackingConfig" } + + override predicate isSource(DataFlow::Node source) { // A source coming from a remote location source instanceof RemoteFlowSource or @@ -90,7 +92,7 @@ module UnsafeUnpackConfig implements DataFlow::ConfigSig { source.(AttrRead).getAttributeName() = "FILES" } - predicate isSink(DataFlow::Node sink) { + override predicate isSink(DataFlow::Node sink) { ( // A sink capturing method calls to `unpack_archive`. sink = API::moduleImport("shutil").getMember("unpack_archive").getACall().getArg(0) @@ -134,7 +136,7 @@ module UnsafeUnpackConfig implements DataFlow::ConfigSig { not sink.getScope().getLocation().getFile().inStdlib() } - predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { // Reading the response nodeTo.(MethodCallNode).calls(nodeFrom, "read") or @@ -209,6 +211,3 @@ module UnsafeUnpackConfig implements DataFlow::ConfigSig { ) } } - -/** Global taint-tracking for detecting "UnsafeUnpacking" vulnerabilities. */ -module UnsafeUnpackFlow = TaintTracking::Global; diff --git a/python/ql/src/experimental/semmle/python/libraries/SmtpLib.qll b/python/ql/src/experimental/semmle/python/libraries/SmtpLib.qll index 7ecbbc1beba..83ea49cbb66 100644 --- a/python/ql/src/experimental/semmle/python/libraries/SmtpLib.qll +++ b/python/ql/src/experimental/semmle/python/libraries/SmtpLib.qll @@ -2,7 +2,7 @@ private import python private import semmle.python.dataflow.new.DataFlow private import experimental.semmle.python.Concepts private import semmle.python.ApiGraphs -private import semmle.python.dataflow.new.TaintTracking +private import semmle.python.dataflow.new.TaintTracking2 module SmtpLib { /** Gets a reference to `smtplib.SMTP_SSL` */ @@ -31,16 +31,16 @@ module SmtpLib { * argument. Used because of the impossibility to get local source nodes from `_subparts`' * `(List|Tuple)` elements. */ - private module SmtpMessageConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source = mimeText(_) } + private class SmtpMessageConfig extends TaintTracking2::Configuration { + SmtpMessageConfig() { this = "SMTPMessageConfig" } - predicate isSink(DataFlow::Node sink) { + override predicate isSource(DataFlow::Node source) { source = mimeText(_) } + + override predicate isSink(DataFlow::Node sink) { sink = smtpMimeMultipartInstance().getACall().getArgByName("_subparts") } } - module SmtpMessageFlow = TaintTracking::Global; - /** * Using the `MimeText` call retrieves the content argument whose type argument equals `mimetype`. * This call flows into `MIMEMultipart`'s `_subparts` argument or the `.attach()` method call @@ -87,7 +87,8 @@ module SmtpLib { sink = [sendCall.getArg(2), sendCall.getArg(2).(DataFlow::MethodCallNode).getObject()] .getALocalSource() and - SmtpMessageFlow::flow(source, sink.(DataFlow::CallCfgNode).getArgByName("_subparts")) + any(SmtpMessageConfig a) + .hasFlow(source, sink.(DataFlow::CallCfgNode).getArgByName("_subparts")) or // via .attach() sink = smtpMimeMultipartInstance().getReturn().getMember("attach").getACall() and diff --git a/python/ql/src/experimental/semmle/python/security/InsecureRandomness.qll b/python/ql/src/experimental/semmle/python/security/InsecureRandomness.qll index 5a32a887bd5..5ad5e2553a5 100644 --- a/python/ql/src/experimental/semmle/python/security/InsecureRandomness.qll +++ b/python/ql/src/experimental/semmle/python/security/InsecureRandomness.qll @@ -21,14 +21,17 @@ module InsecureRandomness { * A taint-tracking configuration for reasoning about random values that are * not cryptographically secure. */ - private module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } + class Configuration extends TaintTracking::Configuration { + Configuration() { this = "InsecureRandomness" } - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + override predicate isSource(DataFlow::Node source) { source instanceof Source } - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } + + deprecated override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { + guard instanceof SanitizerGuard + } } - - /** Global taint-tracking for detecting "random values that are not cryptographically secure" vulnerabilities. */ - module Flow = TaintTracking::Global; } diff --git a/python/ql/src/experimental/semmle/python/security/LdapInsecureAuth.qll b/python/ql/src/experimental/semmle/python/security/LDAPInsecureAuth.qll similarity index 90% rename from python/ql/src/experimental/semmle/python/security/LdapInsecureAuth.qll rename to python/ql/src/experimental/semmle/python/security/LDAPInsecureAuth.qll index e8249dcdff7..56fffe3a2a0 100644 --- a/python/ql/src/experimental/semmle/python/security/LdapInsecureAuth.qll +++ b/python/ql/src/experimental/semmle/python/security/LDAPInsecureAuth.qll @@ -88,8 +88,10 @@ class LdapStringVar extends BinaryExpr { /** * A taint-tracking configuration for detecting LDAP insecure authentications. */ -private module LdapInsecureAuthConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { +class LdapInsecureAuthConfig extends TaintTracking::Configuration { + LdapInsecureAuthConfig() { this = "LDAPInsecureAuthConfig" } + + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource or source.asExpr() instanceof LdapFullHost or source.asExpr() instanceof LdapBothStrings or @@ -98,10 +100,7 @@ private module LdapInsecureAuthConfig implements DataFlow::ConfigSig { source.asExpr() instanceof LdapStringVar } - predicate isSink(DataFlow::Node sink) { + override predicate isSink(DataFlow::Node sink) { exists(LdapBind ldapBind | not ldapBind.useSsl() and sink = ldapBind.getHost()) } } - -/** Global taint-tracking for detecting "LDAP insecure authentications" vulnerabilities. */ -module LdapInsecureAuthFlow = TaintTracking::Global; diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index f072f212305..4df7752e64d 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -1,6 +1,8 @@ private import python +private import semmle.python.dataflow.new.TaintTracking2 private import semmle.python.dataflow.new.TaintTracking private import semmle.python.dataflow.new.DataFlow +private import semmle.python.dataflow.new.DataFlow2 private import semmle.python.ApiGraphs private import semmle.python.dataflow.new.RemoteFlowSources private import semmle.python.frameworks.Flask @@ -162,7 +164,9 @@ class NonConstantTimeComparisonSink extends DataFlow::Node { /** Holds if remote user input was used in the comparison. */ predicate includesUserInput() { - UserInputInComparisonFlow::flowTo(DataFlow::exprNode(anotherParameter)) + exists(UserInputInComparisonConfig config | + config.hasFlowTo(DataFlow2::exprNode(anotherParameter)) + ) } } @@ -173,7 +177,9 @@ class SecretSource extends DataFlow::Node { SecretSource() { secret = this.asExpr() } /** Holds if the secret was deliverd by remote user. */ - predicate includesUserInput() { UserInputSecretFlow::flowTo(DataFlow::exprNode(secret)) } + predicate includesUserInput() { + exists(UserInputSecretConfig config | config.hasFlowTo(DataFlow2::exprNode(secret))) + } } /** A string for `match` that identifies strings that look like they represent secret data. */ @@ -261,21 +267,23 @@ private string sensitiveheaders() { /** * A config that tracks data flow from remote user input to Variable that hold sensitive info */ -module UserInputSecretConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } +class UserInputSecretConfig extends TaintTracking::Configuration { + UserInputSecretConfig() { this = "UserInputSecretConfig" } - predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof CredentialExpr } + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof CredentialExpr } } -module UserInputSecretFlow = TaintTracking::Global; - /** * A config that tracks data flow from remote user input to Equality test */ -module UserInputInComparisonConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } +class UserInputInComparisonConfig extends TaintTracking2::Configuration { + UserInputInComparisonConfig() { this = "UserInputInComparisonConfig" } - predicate isSink(DataFlow::Node sink) { + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { exists(Compare cmp, Expr left, Expr right, Cmpop cmpop | cmpop.getSymbol() = ["==", "in", "is not", "!="] and cmp.compares(left, cmpop, right) and @@ -284,15 +292,15 @@ module UserInputInComparisonConfig implements DataFlow::ConfigSig { } } -module UserInputInComparisonFlow = TaintTracking::Global; - /** * A configuration tracing flow from a client Secret obtained by an HTTP header to a len() function. */ -private module ExcludeLenFuncConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof ClientSuppliedSecret } +private class ExcludeLenFunc extends TaintTracking2::Configuration { + ExcludeLenFunc() { this = "ExcludeLenFunc" } - predicate isSink(DataFlow::Node sink) { + override predicate isSource(DataFlow::Node source) { source instanceof ClientSuppliedSecret } + + override predicate isSink(DataFlow::Node sink) { exists(Call call | call.getFunc().(Name).getId() = "len" and sink.asExpr() = call.getArg(0) @@ -300,8 +308,6 @@ private module ExcludeLenFuncConfig implements DataFlow::ConfigSig { } } -module ExcludeLenFuncFlow = TaintTracking::Global; - /** * Holds if there is a fast-fail check. */ @@ -337,7 +343,8 @@ class CompareSink extends DataFlow::Node { * Holds if there is a flow to len(). */ predicate flowtolen() { - // TODO: Fly by comment: I don't understand this code at all, seems very strange. - ExcludeLenFuncFlow::flowPath(_, _) + exists(ExcludeLenFunc config, DataFlow2::PathNode source, DataFlow2::PathNode sink | + config.hasFlowPath(source, sink) + ) } } diff --git a/python/ql/src/experimental/semmle/python/security/ZipSlip.qll b/python/ql/src/experimental/semmle/python/security/ZipSlip.qll index 5f8b4d940ef..59f558c67d6 100644 --- a/python/ql/src/experimental/semmle/python/security/ZipSlip.qll +++ b/python/ql/src/experimental/semmle/python/security/ZipSlip.qll @@ -4,8 +4,10 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.ApiGraphs import semmle.python.dataflow.new.TaintTracking -private module ZipSlipConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { +class ZipSlipConfig extends TaintTracking::Configuration { + ZipSlipConfig() { this = "ZipSlipConfig" } + + override predicate isSource(DataFlow::Node source) { ( source = API::moduleImport("zipfile").getMember("ZipFile").getReturn().getMember("open").getACall() or @@ -27,7 +29,7 @@ private module ZipSlipConfig implements DataFlow::ConfigSig { not source.getScope().getLocation().getFile().inStdlib() } - predicate isSink(DataFlow::Node sink) { + override predicate isSink(DataFlow::Node sink) { ( sink = any(CopyFile copyfile).getAPathArgument() or sink = any(CopyFile copyfile).getfsrcArgument() @@ -35,6 +37,3 @@ private module ZipSlipConfig implements DataFlow::ConfigSig { not sink.getScope().getLocation().getFile().inStdlib() } } - -/** Global taint-tracking for detecting "zip slip" vulnerabilities. */ -module ZipSlipFlow = TaintTracking::Global; diff --git a/python/ql/src/experimental/semmle/python/security/dataflow/EmailXss.qll b/python/ql/src/experimental/semmle/python/security/dataflow/ReflectedXSS.qll similarity index 51% rename from python/ql/src/experimental/semmle/python/security/dataflow/EmailXss.qll rename to python/ql/src/experimental/semmle/python/security/dataflow/ReflectedXSS.qll index 88e9af89ba6..b35cb405dc0 100644 --- a/python/ql/src/experimental/semmle/python/security/dataflow/EmailXss.qll +++ b/python/ql/src/experimental/semmle/python/security/dataflow/ReflectedXSS.qll @@ -1,5 +1,6 @@ /** - * Provides a taint-tracking configuration for detecting "Email XSS" vulnerabilities. + * Provides a taint-tracking configuration for detecting reflected server-side + * cross-site scripting vulnerabilities. */ import python @@ -11,18 +12,24 @@ import experimental.semmle.python.Concepts import semmle.python.Concepts import semmle.python.ApiGraphs -private module EmailXssConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } +/** + * A taint-tracking configuration for detecting reflected server-side cross-site + * scripting vulnerabilities. + */ +class ReflectedXssConfiguration extends TaintTracking::Configuration { + ReflectedXssConfiguration() { this = "ReflectedXssConfiguration" } - predicate isSink(DataFlow::Node sink) { sink = any(EmailSender email).getHtmlBody() } + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - predicate isBarrier(DataFlow::Node sanitizer) { + override predicate isSink(DataFlow::Node sink) { sink = any(EmailSender email).getHtmlBody() } + + override predicate isSanitizer(DataFlow::Node sanitizer) { sanitizer = any(HtmlEscaping esc).getOutput() or sanitizer instanceof StringConstCompareBarrier } - predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { exists(DataFlow::CallCfgNode htmlContentCall | htmlContentCall = API::moduleImport("sendgrid") @@ -35,6 +42,3 @@ private module EmailXssConfig implements DataFlow::ConfigSig { ) } } - -/** Global taint-tracking for detecting "Email XSS" vulnerabilities. */ -module EmailXssFlow = TaintTracking::Global; diff --git a/python/ql/src/experimental/semmle/python/security/injection/CookieInjection.qll b/python/ql/src/experimental/semmle/python/security/injection/CookieInjection.qll index 5d31b9f8b51..87f3b1fd76b 100644 --- a/python/ql/src/experimental/semmle/python/security/injection/CookieInjection.qll +++ b/python/ql/src/experimental/semmle/python/security/injection/CookieInjection.qll @@ -29,13 +29,12 @@ class CookieSink extends DataFlow::Node { /** * A taint-tracking configuration for detecting Cookie injections. */ -private module CookieInjectionConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } +class CookieInjectionFlowConfig extends TaintTracking::Configuration { + CookieInjectionFlowConfig() { this = "CookieInjectionFlowConfig" } - predicate isSink(DataFlow::Node sink) { + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { exists(Cookie c | sink in [c.getNameArg(), c.getValueArg()]) } } - -/** Global taint-tracking for detecting "Cookie injections" vulnerabilities. */ -module CookieInjectionFlow = TaintTracking::Global; diff --git a/python/ql/src/experimental/semmle/python/security/injection/CsvInjection.qll b/python/ql/src/experimental/semmle/python/security/injection/CsvInjection.qll index 316dd4d2603..c6197222d91 100644 --- a/python/ql/src/experimental/semmle/python/security/injection/CsvInjection.qll +++ b/python/ql/src/experimental/semmle/python/security/injection/CsvInjection.qll @@ -8,12 +8,14 @@ import semmle.python.dataflow.new.RemoteFlowSources /** * A taint-tracking configuration for tracking untrusted user input used in file read. */ -private module CsvInjectionConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } +class CsvInjectionFlowConfig extends TaintTracking::Configuration { + CsvInjectionFlowConfig() { this = "CsvInjectionFlowConfig" } - predicate isSink(DataFlow::Node sink) { sink = any(CsvWriter cw).getAnInput() } + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - predicate isBarrier(DataFlow::Node node) { + override predicate isSink(DataFlow::Node sink) { sink = any(CsvWriter cw).getAnInput() } + + override predicate isSanitizer(DataFlow::Node node) { node = DataFlow::BarrierGuard::getABarrierNode() or node instanceof StringConstCompareBarrier } @@ -27,6 +29,3 @@ private predicate startsWithCheck(DataFlow::GuardNode g, ControlFlowNode node, b branch = true ) } - -/** Global taint-tracking for detecting "CSV injection" vulnerabilities. */ -module CsvInjectionFlow = TaintTracking::Global; diff --git a/python/ql/src/experimental/semmle/python/security/injection/HTTPHeaders.qll b/python/ql/src/experimental/semmle/python/security/injection/HTTPHeaders.qll index 0768d7a84b2..4ba70cd37a2 100644 --- a/python/ql/src/experimental/semmle/python/security/injection/HTTPHeaders.qll +++ b/python/ql/src/experimental/semmle/python/security/injection/HTTPHeaders.qll @@ -7,15 +7,14 @@ import semmle.python.dataflow.new.RemoteFlowSources /** * A taint-tracking configuration for detecting HTTP Header injections. */ -private module HeaderInjectionConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } +class HeaderInjectionFlowConfig extends TaintTracking::Configuration { + HeaderInjectionFlowConfig() { this = "HeaderInjectionFlowConfig" } - predicate isSink(DataFlow::Node sink) { + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { exists(HeaderDeclaration headerDeclaration | sink in [headerDeclaration.getNameArg(), headerDeclaration.getValueArg()] ) } } - -/** Global taint-tracking for detecting "HTTP Header injection" vulnerabilities. */ -module HeaderInjectionFlow = TaintTracking::Global; diff --git a/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll b/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll index a0838772515..24103a33ace 100644 --- a/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll +++ b/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll @@ -16,11 +16,9 @@ module ModificationOfParameterWithDefault { import ModificationOfParameterWithDefaultCustomizations::ModificationOfParameterWithDefault /** - * DEPRECATED: Use `Flow` module instead. - * * A data-flow configuration for detecting modifications of a parameters default value. */ - deprecated class Configuration extends DataFlow::Configuration { + class Configuration extends DataFlow::Configuration { /** Record whether the default value being tracked is non-empty. */ boolean nonEmptyDefault; @@ -45,33 +43,4 @@ module ModificationOfParameterWithDefault { nonEmptyDefault = false and node instanceof MustBeNonEmpty } } - - private module Config implements DataFlow::StateConfigSig { - class FlowState = boolean; - - predicate isSource(DataFlow::Node source, FlowState state) { - source.(Source).isNonEmpty() = state - } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isSink(DataFlow::Node sink, FlowState state) { - // dummy implementation since this predicate is required, but actual logic is in - // the predicate above. - none() - } - - predicate isBarrier(DataFlow::Node node, FlowState state) { - // if we are tracking a non-empty default, then it is ok to modify empty values, - // so our tracking ends at those. - state = true and node instanceof MustBeEmpty - or - // if we are tracking a empty default, then it is ok to modify non-empty values, - // so our tracking ends at those. - state = false and node instanceof MustBeNonEmpty - } - } - - /** Global data-flow for detecting modifications of a parameters default value. */ - module Flow = DataFlow::GlobalWithState; } diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected index a699a1bac5f..52fd49e57b1 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected @@ -33,8 +33,7 @@ edges | TarSlipImprov.py:141:34:141:36 | GSSA Variable tar | TarSlipImprov.py:142:9:142:13 | GSSA Variable entry | | TarSlipImprov.py:142:9:142:13 | GSSA Variable entry | TarSlipImprov.py:143:36:143:40 | ControlFlowNode for entry | | TarSlipImprov.py:159:9:159:14 | SSA variable tar_cm | TarSlipImprov.py:162:20:162:23 | SSA variable tarc | -| TarSlipImprov.py:159:18:159:52 | ControlFlowNode for closing() | TarSlipImprov.py:159:9:159:14 | SSA variable tar_cm | -| TarSlipImprov.py:159:26:159:51 | ControlFlowNode for Attribute() | TarSlipImprov.py:159:18:159:52 | ControlFlowNode for closing() | +| TarSlipImprov.py:159:26:159:51 | ControlFlowNode for Attribute() | TarSlipImprov.py:159:9:159:14 | SSA variable tar_cm | | TarSlipImprov.py:162:20:162:23 | SSA variable tarc | TarSlipImprov.py:169:9:169:12 | ControlFlowNode for tarc | | TarSlipImprov.py:176:6:176:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:176:36:176:38 | GSSA Variable tar | | TarSlipImprov.py:176:36:176:38 | GSSA Variable tar | TarSlipImprov.py:177:9:177:13 | GSSA Variable entry | @@ -123,7 +122,6 @@ nodes | TarSlipImprov.py:142:9:142:13 | GSSA Variable entry | semmle.label | GSSA Variable entry | | TarSlipImprov.py:143:36:143:40 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | | TarSlipImprov.py:159:9:159:14 | SSA variable tar_cm | semmle.label | SSA variable tar_cm | -| TarSlipImprov.py:159:18:159:52 | ControlFlowNode for closing() | semmle.label | ControlFlowNode for closing() | | TarSlipImprov.py:159:26:159:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:162:20:162:23 | SSA variable tarc | semmle.label | SSA variable tarc | | TarSlipImprov.py:169:9:169:12 | ControlFlowNode for tarc | semmle.label | ControlFlowNode for tarc | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.expected index 9ce23b4c553..04431311999 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.expected @@ -1,3 +1,3 @@ missingAnnotationOnSink -testFailures failures +testFailures diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.ql b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.ql index ed7d650f536..91a6cdaa14a 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.ql +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.ql @@ -1,4 +1,4 @@ import python import experimental.dataflow.TestUtil.DataflowQueryTest import experimental.Security.UnsafeUnpackQuery -import FromTaintTrackingConfig +import FromLegacyConfiguration diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected index f8921911e4f..b05f536c26d 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected @@ -1,86 +1,43 @@ edges | UnsafeUnpack.py:5:26:5:32 | ControlFlowNode for ImportMember | UnsafeUnpack.py:5:26:5:32 | GSSA Variable request | | UnsafeUnpack.py:5:26:5:32 | GSSA Variable request | UnsafeUnpack.py:11:18:11:24 | ControlFlowNode for request | -| UnsafeUnpack.py:11:7:11:14 | SSA variable filename | UnsafeUnpack.py:13:24:13:58 | ControlFlowNode for Attribute() | +| UnsafeUnpack.py:11:7:11:14 | SSA variable filename | UnsafeUnpack.py:13:13:13:20 | SSA variable response | +| UnsafeUnpack.py:11:18:11:24 | ControlFlowNode for request | UnsafeUnpack.py:11:7:11:14 | SSA variable filename | | UnsafeUnpack.py:11:18:11:24 | ControlFlowNode for request | UnsafeUnpack.py:11:18:11:29 | ControlFlowNode for Attribute | | UnsafeUnpack.py:11:18:11:29 | ControlFlowNode for Attribute | UnsafeUnpack.py:11:18:11:49 | ControlFlowNode for Attribute() | | UnsafeUnpack.py:11:18:11:49 | ControlFlowNode for Attribute() | UnsafeUnpack.py:11:7:11:14 | SSA variable filename | -| UnsafeUnpack.py:13:13:13:20 | SSA variable response | UnsafeUnpack.py:17:27:17:34 | ControlFlowNode for response | -| UnsafeUnpack.py:13:24:13:58 | ControlFlowNode for Attribute() | UnsafeUnpack.py:13:13:13:20 | SSA variable response | -| UnsafeUnpack.py:16:23:16:29 | ControlFlowNode for tarpath | UnsafeUnpack.py:19:35:19:41 | ControlFlowNode for tarpath | -| UnsafeUnpack.py:17:19:17:19 | ControlFlowNode for f | UnsafeUnpack.py:16:23:16:29 | ControlFlowNode for tarpath | -| UnsafeUnpack.py:17:27:17:34 | ControlFlowNode for response | UnsafeUnpack.py:17:27:17:38 | ControlFlowNode for Attribute | -| UnsafeUnpack.py:17:27:17:38 | ControlFlowNode for Attribute | UnsafeUnpack.py:17:27:17:45 | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:17:27:17:45 | ControlFlowNode for Attribute() | UnsafeUnpack.py:17:19:17:19 | ControlFlowNode for f | +| UnsafeUnpack.py:13:13:13:20 | SSA variable response | UnsafeUnpack.py:19:35:19:41 | ControlFlowNode for tarpath | | UnsafeUnpack.py:33:50:33:65 | ControlFlowNode for local_ziped_path | UnsafeUnpack.py:34:23:34:38 | ControlFlowNode for local_ziped_path | | UnsafeUnpack.py:47:20:47:34 | ControlFlowNode for compressed_file | UnsafeUnpack.py:48:23:48:37 | ControlFlowNode for compressed_file | | UnsafeUnpack.py:51:1:51:15 | GSSA Variable compressed_file | UnsafeUnpack.py:52:23:52:37 | ControlFlowNode for compressed_file | | UnsafeUnpack.py:51:19:51:36 | ControlFlowNode for Attribute() | UnsafeUnpack.py:51:1:51:15 | GSSA Variable compressed_file | | UnsafeUnpack.py:65:1:65:15 | GSSA Variable compressed_file | UnsafeUnpack.py:66:23:66:37 | ControlFlowNode for compressed_file | | UnsafeUnpack.py:65:19:65:31 | ControlFlowNode for Attribute | UnsafeUnpack.py:65:1:65:15 | GSSA Variable compressed_file | -| UnsafeUnpack.py:79:1:79:12 | GSSA Variable url_filename | UnsafeUnpack.py:81:12:81:50 | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:79:1:79:12 | GSSA Variable url_filename | UnsafeUnpack.py:171:12:171:50 | ControlFlowNode for Attribute() | +| UnsafeUnpack.py:79:1:79:12 | GSSA Variable url_filename | UnsafeUnpack.py:81:1:81:8 | GSSA Variable response | +| UnsafeUnpack.py:79:1:79:12 | GSSA Variable url_filename | UnsafeUnpack.py:171:1:171:8 | GSSA Variable response | | UnsafeUnpack.py:79:16:79:28 | ControlFlowNode for Attribute | UnsafeUnpack.py:79:1:79:12 | GSSA Variable url_filename | -| UnsafeUnpack.py:81:1:81:8 | GSSA Variable response | UnsafeUnpack.py:85:15:85:22 | ControlFlowNode for response | -| UnsafeUnpack.py:81:12:81:50 | ControlFlowNode for Attribute() | UnsafeUnpack.py:81:1:81:8 | GSSA Variable response | -| UnsafeUnpack.py:84:11:84:17 | ControlFlowNode for tarpath | UnsafeUnpack.py:87:23:87:29 | ControlFlowNode for tarpath | -| UnsafeUnpack.py:85:7:85:7 | ControlFlowNode for f | UnsafeUnpack.py:84:11:84:17 | ControlFlowNode for tarpath | -| UnsafeUnpack.py:85:15:85:22 | ControlFlowNode for response | UnsafeUnpack.py:85:15:85:26 | ControlFlowNode for Attribute | -| UnsafeUnpack.py:85:15:85:26 | ControlFlowNode for Attribute | UnsafeUnpack.py:85:15:85:33 | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:85:15:85:33 | ControlFlowNode for Attribute() | UnsafeUnpack.py:85:7:85:7 | ControlFlowNode for f | -| UnsafeUnpack.py:102:23:102:30 | ControlFlowNode for savepath | UnsafeUnpack.py:105:35:105:42 | ControlFlowNode for savepath | -| UnsafeUnpack.py:103:23:103:27 | SSA variable chunk | UnsafeUnpack.py:104:37:104:41 | ControlFlowNode for chunk | -| UnsafeUnpack.py:103:32:103:44 | ControlFlowNode for Attribute | UnsafeUnpack.py:103:32:103:54 | ControlFlowNode for Subscript | -| UnsafeUnpack.py:103:32:103:54 | ControlFlowNode for Subscript | UnsafeUnpack.py:103:32:103:63 | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:103:32:103:63 | ControlFlowNode for Attribute() | UnsafeUnpack.py:103:23:103:27 | SSA variable chunk | -| UnsafeUnpack.py:104:25:104:29 | ControlFlowNode for wfile | UnsafeUnpack.py:102:23:102:30 | ControlFlowNode for savepath | -| UnsafeUnpack.py:104:37:104:41 | ControlFlowNode for chunk | UnsafeUnpack.py:104:25:104:29 | ControlFlowNode for wfile | -| UnsafeUnpack.py:108:13:108:18 | SSA variable myfile | UnsafeUnpack.py:111:27:111:32 | ControlFlowNode for myfile | +| UnsafeUnpack.py:81:1:81:8 | GSSA Variable response | UnsafeUnpack.py:87:23:87:29 | ControlFlowNode for tarpath | +| UnsafeUnpack.py:103:23:103:27 | SSA variable chunk | UnsafeUnpack.py:105:35:105:42 | ControlFlowNode for savepath | +| UnsafeUnpack.py:103:32:103:44 | ControlFlowNode for Attribute | UnsafeUnpack.py:103:23:103:27 | SSA variable chunk | +| UnsafeUnpack.py:108:13:108:18 | SSA variable myfile | UnsafeUnpack.py:112:35:112:43 | ControlFlowNode for file_path | +| UnsafeUnpack.py:108:22:108:34 | ControlFlowNode for Attribute | UnsafeUnpack.py:108:13:108:18 | SSA variable myfile | | UnsafeUnpack.py:108:22:108:34 | ControlFlowNode for Attribute | UnsafeUnpack.py:108:22:108:48 | ControlFlowNode for Attribute() | | UnsafeUnpack.py:108:22:108:48 | ControlFlowNode for Attribute() | UnsafeUnpack.py:108:13:108:18 | SSA variable myfile | -| UnsafeUnpack.py:110:18:110:26 | ControlFlowNode for file_path | UnsafeUnpack.py:112:35:112:43 | ControlFlowNode for file_path | -| UnsafeUnpack.py:111:19:111:19 | ControlFlowNode for f | UnsafeUnpack.py:110:18:110:26 | ControlFlowNode for file_path | -| UnsafeUnpack.py:111:27:111:32 | ControlFlowNode for myfile | UnsafeUnpack.py:111:27:111:39 | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:111:27:111:39 | ControlFlowNode for Attribute() | UnsafeUnpack.py:111:19:111:19 | ControlFlowNode for f | -| UnsafeUnpack.py:116:17:116:21 | SSA variable ufile | UnsafeUnpack.py:118:38:118:42 | ControlFlowNode for ufile | -| UnsafeUnpack.py:116:27:116:39 | ControlFlowNode for Attribute | UnsafeUnpack.py:116:27:116:49 | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:116:27:116:49 | ControlFlowNode for Attribute() | UnsafeUnpack.py:116:17:116:21 | SSA variable ufile | -| UnsafeUnpack.py:118:19:118:26 | SSA variable filename | UnsafeUnpack.py:119:48:119:55 | ControlFlowNode for filename | -| UnsafeUnpack.py:118:30:118:55 | ControlFlowNode for Attribute() | UnsafeUnpack.py:118:19:118:26 | SSA variable filename | -| UnsafeUnpack.py:118:38:118:42 | ControlFlowNode for ufile | UnsafeUnpack.py:118:38:118:47 | ControlFlowNode for Attribute | -| UnsafeUnpack.py:118:38:118:47 | ControlFlowNode for Attribute | UnsafeUnpack.py:118:30:118:55 | ControlFlowNode for Attribute() | +| UnsafeUnpack.py:116:17:116:21 | SSA variable ufile | UnsafeUnpack.py:118:19:118:26 | SSA variable filename | +| UnsafeUnpack.py:116:27:116:39 | ControlFlowNode for Attribute | UnsafeUnpack.py:116:17:116:21 | SSA variable ufile | +| UnsafeUnpack.py:118:19:118:26 | SSA variable filename | UnsafeUnpack.py:119:19:119:36 | SSA variable uploaded_file_path | | UnsafeUnpack.py:119:19:119:36 | SSA variable uploaded_file_path | UnsafeUnpack.py:120:41:120:58 | ControlFlowNode for uploaded_file_path | -| UnsafeUnpack.py:119:40:119:56 | ControlFlowNode for Attribute() | UnsafeUnpack.py:119:19:119:36 | SSA variable uploaded_file_path | -| UnsafeUnpack.py:119:48:119:55 | ControlFlowNode for filename | UnsafeUnpack.py:119:40:119:56 | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:140:1:140:19 | GSSA Variable unsafe_filename_tar | UnsafeUnpack.py:141:22:141:40 | ControlFlowNode for unsafe_filename_tar | +| UnsafeUnpack.py:140:1:140:19 | GSSA Variable unsafe_filename_tar | UnsafeUnpack.py:141:56:141:58 | GSSA Variable tar | | UnsafeUnpack.py:140:23:140:35 | ControlFlowNode for Attribute | UnsafeUnpack.py:140:1:140:19 | GSSA Variable unsafe_filename_tar | -| UnsafeUnpack.py:141:6:141:51 | ControlFlowNode for Attribute() | UnsafeUnpack.py:141:56:141:58 | GSSA Variable tar | -| UnsafeUnpack.py:141:22:141:40 | ControlFlowNode for unsafe_filename_tar | UnsafeUnpack.py:141:6:141:51 | ControlFlowNode for Attribute() | | UnsafeUnpack.py:141:56:141:58 | GSSA Variable tar | UnsafeUnpack.py:142:49:142:51 | ControlFlowNode for tar | -| UnsafeUnpack.py:157:23:157:30 | ControlFlowNode for savepath | UnsafeUnpack.py:161:38:161:45 | ControlFlowNode for savepath | -| UnsafeUnpack.py:158:23:158:27 | SSA variable chunk | UnsafeUnpack.py:159:37:159:41 | ControlFlowNode for chunk | -| UnsafeUnpack.py:158:32:158:44 | ControlFlowNode for Attribute | UnsafeUnpack.py:158:32:158:54 | ControlFlowNode for Subscript | -| UnsafeUnpack.py:158:32:158:54 | ControlFlowNode for Subscript | UnsafeUnpack.py:158:32:158:63 | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:158:32:158:63 | ControlFlowNode for Attribute() | UnsafeUnpack.py:158:23:158:27 | SSA variable chunk | -| UnsafeUnpack.py:159:25:159:29 | ControlFlowNode for wfile | UnsafeUnpack.py:157:23:157:30 | ControlFlowNode for savepath | -| UnsafeUnpack.py:159:37:159:41 | ControlFlowNode for chunk | UnsafeUnpack.py:159:25:159:29 | ControlFlowNode for wfile | -| UnsafeUnpack.py:161:19:161:21 | SSA variable tar | UnsafeUnpack.py:163:33:163:35 | ControlFlowNode for tar | -| UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | UnsafeUnpack.py:161:19:161:21 | SSA variable tar | -| UnsafeUnpack.py:161:38:161:45 | ControlFlowNode for savepath | UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | +| UnsafeUnpack.py:158:23:158:27 | SSA variable chunk | UnsafeUnpack.py:161:19:161:21 | SSA variable tar | +| UnsafeUnpack.py:158:32:158:44 | ControlFlowNode for Attribute | UnsafeUnpack.py:158:23:158:27 | SSA variable chunk | +| UnsafeUnpack.py:161:19:161:21 | SSA variable tar | UnsafeUnpack.py:163:23:163:28 | SSA variable member | | UnsafeUnpack.py:163:23:163:28 | SSA variable member | UnsafeUnpack.py:166:37:166:42 | ControlFlowNode for member | -| UnsafeUnpack.py:163:33:163:35 | ControlFlowNode for tar | UnsafeUnpack.py:163:23:163:28 | SSA variable member | | UnsafeUnpack.py:166:23:166:28 | [post] ControlFlowNode for result | UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | | UnsafeUnpack.py:166:37:166:42 | ControlFlowNode for member | UnsafeUnpack.py:166:23:166:28 | [post] ControlFlowNode for result | -| UnsafeUnpack.py:171:1:171:8 | GSSA Variable response | UnsafeUnpack.py:174:15:174:22 | ControlFlowNode for response | -| UnsafeUnpack.py:171:12:171:50 | ControlFlowNode for Attribute() | UnsafeUnpack.py:171:1:171:8 | GSSA Variable response | -| UnsafeUnpack.py:173:11:173:17 | ControlFlowNode for tarpath | UnsafeUnpack.py:176:17:176:23 | ControlFlowNode for tarpath | -| UnsafeUnpack.py:174:7:174:7 | ControlFlowNode for f | UnsafeUnpack.py:173:11:173:17 | ControlFlowNode for tarpath | -| UnsafeUnpack.py:174:15:174:22 | ControlFlowNode for response | UnsafeUnpack.py:174:15:174:26 | ControlFlowNode for Attribute | -| UnsafeUnpack.py:174:15:174:26 | ControlFlowNode for Attribute | UnsafeUnpack.py:174:15:174:33 | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:174:15:174:33 | ControlFlowNode for Attribute() | UnsafeUnpack.py:174:7:174:7 | ControlFlowNode for f | -| UnsafeUnpack.py:176:17:176:23 | ControlFlowNode for tarpath | UnsafeUnpack.py:176:1:176:34 | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:194:53:194:55 | ControlFlowNode for tmp | UnsafeUnpack.py:201:29:201:31 | ControlFlowNode for tmp | -| UnsafeUnpack.py:201:29:201:31 | ControlFlowNode for tmp | UnsafeUnpack.py:201:29:201:36 | ControlFlowNode for Attribute | +| UnsafeUnpack.py:171:1:171:8 | GSSA Variable response | UnsafeUnpack.py:176:1:176:34 | ControlFlowNode for Attribute() | +| UnsafeUnpack.py:194:53:194:55 | ControlFlowNode for tmp | UnsafeUnpack.py:201:29:201:36 | ControlFlowNode for Attribute | nodes | UnsafeUnpack.py:5:26:5:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | UnsafeUnpack.py:5:26:5:32 | GSSA Variable request | semmle.label | GSSA Variable request | @@ -89,12 +46,6 @@ nodes | UnsafeUnpack.py:11:18:11:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | UnsafeUnpack.py:11:18:11:49 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | UnsafeUnpack.py:13:13:13:20 | SSA variable response | semmle.label | SSA variable response | -| UnsafeUnpack.py:13:24:13:58 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:16:23:16:29 | ControlFlowNode for tarpath | semmle.label | ControlFlowNode for tarpath | -| UnsafeUnpack.py:17:19:17:19 | ControlFlowNode for f | semmle.label | ControlFlowNode for f | -| UnsafeUnpack.py:17:27:17:34 | ControlFlowNode for response | semmle.label | ControlFlowNode for response | -| UnsafeUnpack.py:17:27:17:38 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| UnsafeUnpack.py:17:27:17:45 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | UnsafeUnpack.py:19:35:19:41 | ControlFlowNode for tarpath | semmle.label | ControlFlowNode for tarpath | | UnsafeUnpack.py:33:50:33:65 | ControlFlowNode for local_ziped_path | semmle.label | ControlFlowNode for local_ziped_path | | UnsafeUnpack.py:34:23:34:38 | ControlFlowNode for local_ziped_path | semmle.label | ControlFlowNode for local_ziped_path | @@ -109,72 +60,33 @@ nodes | UnsafeUnpack.py:79:1:79:12 | GSSA Variable url_filename | semmle.label | GSSA Variable url_filename | | UnsafeUnpack.py:79:16:79:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | UnsafeUnpack.py:81:1:81:8 | GSSA Variable response | semmle.label | GSSA Variable response | -| UnsafeUnpack.py:81:12:81:50 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:84:11:84:17 | ControlFlowNode for tarpath | semmle.label | ControlFlowNode for tarpath | -| UnsafeUnpack.py:85:7:85:7 | ControlFlowNode for f | semmle.label | ControlFlowNode for f | -| UnsafeUnpack.py:85:15:85:22 | ControlFlowNode for response | semmle.label | ControlFlowNode for response | -| UnsafeUnpack.py:85:15:85:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| UnsafeUnpack.py:85:15:85:33 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | UnsafeUnpack.py:87:23:87:29 | ControlFlowNode for tarpath | semmle.label | ControlFlowNode for tarpath | -| UnsafeUnpack.py:102:23:102:30 | ControlFlowNode for savepath | semmle.label | ControlFlowNode for savepath | | UnsafeUnpack.py:103:23:103:27 | SSA variable chunk | semmle.label | SSA variable chunk | | UnsafeUnpack.py:103:32:103:44 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| UnsafeUnpack.py:103:32:103:54 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| UnsafeUnpack.py:103:32:103:63 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:104:25:104:29 | ControlFlowNode for wfile | semmle.label | ControlFlowNode for wfile | -| UnsafeUnpack.py:104:37:104:41 | ControlFlowNode for chunk | semmle.label | ControlFlowNode for chunk | | UnsafeUnpack.py:105:35:105:42 | ControlFlowNode for savepath | semmle.label | ControlFlowNode for savepath | | UnsafeUnpack.py:108:13:108:18 | SSA variable myfile | semmle.label | SSA variable myfile | | UnsafeUnpack.py:108:22:108:34 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | UnsafeUnpack.py:108:22:108:48 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:110:18:110:26 | ControlFlowNode for file_path | semmle.label | ControlFlowNode for file_path | -| UnsafeUnpack.py:111:19:111:19 | ControlFlowNode for f | semmle.label | ControlFlowNode for f | -| UnsafeUnpack.py:111:27:111:32 | ControlFlowNode for myfile | semmle.label | ControlFlowNode for myfile | -| UnsafeUnpack.py:111:27:111:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | UnsafeUnpack.py:112:35:112:43 | ControlFlowNode for file_path | semmle.label | ControlFlowNode for file_path | | UnsafeUnpack.py:116:17:116:21 | SSA variable ufile | semmle.label | SSA variable ufile | | UnsafeUnpack.py:116:27:116:39 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| UnsafeUnpack.py:116:27:116:49 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | UnsafeUnpack.py:118:19:118:26 | SSA variable filename | semmle.label | SSA variable filename | -| UnsafeUnpack.py:118:30:118:55 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:118:38:118:42 | ControlFlowNode for ufile | semmle.label | ControlFlowNode for ufile | -| UnsafeUnpack.py:118:38:118:47 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | UnsafeUnpack.py:119:19:119:36 | SSA variable uploaded_file_path | semmle.label | SSA variable uploaded_file_path | -| UnsafeUnpack.py:119:40:119:56 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:119:48:119:55 | ControlFlowNode for filename | semmle.label | ControlFlowNode for filename | | UnsafeUnpack.py:120:41:120:58 | ControlFlowNode for uploaded_file_path | semmle.label | ControlFlowNode for uploaded_file_path | | UnsafeUnpack.py:140:1:140:19 | GSSA Variable unsafe_filename_tar | semmle.label | GSSA Variable unsafe_filename_tar | | UnsafeUnpack.py:140:23:140:35 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| UnsafeUnpack.py:141:6:141:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:141:22:141:40 | ControlFlowNode for unsafe_filename_tar | semmle.label | ControlFlowNode for unsafe_filename_tar | | UnsafeUnpack.py:141:56:141:58 | GSSA Variable tar | semmle.label | GSSA Variable tar | | UnsafeUnpack.py:142:49:142:51 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | -| UnsafeUnpack.py:157:23:157:30 | ControlFlowNode for savepath | semmle.label | ControlFlowNode for savepath | | UnsafeUnpack.py:158:23:158:27 | SSA variable chunk | semmle.label | SSA variable chunk | | UnsafeUnpack.py:158:32:158:44 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| UnsafeUnpack.py:158:32:158:54 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| UnsafeUnpack.py:158:32:158:63 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:159:25:159:29 | ControlFlowNode for wfile | semmle.label | ControlFlowNode for wfile | -| UnsafeUnpack.py:159:37:159:41 | ControlFlowNode for chunk | semmle.label | ControlFlowNode for chunk | | UnsafeUnpack.py:161:19:161:21 | SSA variable tar | semmle.label | SSA variable tar | -| UnsafeUnpack.py:161:25:161:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:161:38:161:45 | ControlFlowNode for savepath | semmle.label | ControlFlowNode for savepath | | UnsafeUnpack.py:163:23:163:28 | SSA variable member | semmle.label | SSA variable member | -| UnsafeUnpack.py:163:33:163:35 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | | UnsafeUnpack.py:166:23:166:28 | [post] ControlFlowNode for result | semmle.label | [post] ControlFlowNode for result | | UnsafeUnpack.py:166:37:166:42 | ControlFlowNode for member | semmle.label | ControlFlowNode for member | | UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | semmle.label | ControlFlowNode for result | | UnsafeUnpack.py:171:1:171:8 | GSSA Variable response | semmle.label | GSSA Variable response | -| UnsafeUnpack.py:171:12:171:50 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:173:11:173:17 | ControlFlowNode for tarpath | semmle.label | ControlFlowNode for tarpath | -| UnsafeUnpack.py:174:7:174:7 | ControlFlowNode for f | semmle.label | ControlFlowNode for f | -| UnsafeUnpack.py:174:15:174:22 | ControlFlowNode for response | semmle.label | ControlFlowNode for response | -| UnsafeUnpack.py:174:15:174:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| UnsafeUnpack.py:174:15:174:33 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | UnsafeUnpack.py:176:1:176:34 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:176:17:176:23 | ControlFlowNode for tarpath | semmle.label | ControlFlowNode for tarpath | | UnsafeUnpack.py:194:53:194:55 | ControlFlowNode for tmp | semmle.label | ControlFlowNode for tmp | -| UnsafeUnpack.py:201:29:201:31 | ControlFlowNode for tmp | semmle.label | ControlFlowNode for tmp | | UnsafeUnpack.py:201:29:201:36 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | subpaths #select diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-paramiko/paramiko.expected b/python/ql/test/experimental/query-tests/Security/CWE-074-paramiko/paramiko.expected index b31006425a6..85e1e7b326d 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-paramiko/paramiko.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-074-paramiko/paramiko.expected @@ -1,8 +1,7 @@ edges | paramiko.py:15:21:15:23 | ControlFlowNode for cmd | paramiko.py:16:62:16:64 | ControlFlowNode for cmd | | paramiko.py:20:21:20:23 | ControlFlowNode for cmd | paramiko.py:21:70:21:72 | ControlFlowNode for cmd | -| paramiko.py:25:21:25:23 | ControlFlowNode for cmd | paramiko.py:26:136:26:138 | ControlFlowNode for cmd | -| paramiko.py:26:136:26:138 | ControlFlowNode for cmd | paramiko.py:26:114:26:139 | ControlFlowNode for Attribute() | +| paramiko.py:25:21:25:23 | ControlFlowNode for cmd | paramiko.py:26:114:26:139 | ControlFlowNode for Attribute() | nodes | paramiko.py:15:21:15:23 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd | | paramiko.py:16:62:16:64 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd | @@ -10,7 +9,6 @@ nodes | paramiko.py:21:70:21:72 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd | | paramiko.py:25:21:25:23 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd | | paramiko.py:26:114:26:139 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| paramiko.py:26:136:26:138 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd | subpaths #select | paramiko.py:16:62:16:64 | ControlFlowNode for cmd | paramiko.py:15:21:15:23 | ControlFlowNode for cmd | paramiko.py:16:62:16:64 | ControlFlowNode for cmd | This code execution depends on a $@. | paramiko.py:15:21:15:23 | ControlFlowNode for cmd | a user-provided value | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/EmailXss.qlref b/python/ql/test/experimental/query-tests/Security/CWE-079/EmailXss.qlref deleted file mode 100644 index fcc132dd66c..00000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-079/EmailXss.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security/CWE-079/EmailXss.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/EmailXss.expected b/python/ql/test/experimental/query-tests/Security/CWE-079/ReflectedXSS.expected similarity index 97% rename from python/ql/test/experimental/query-tests/Security/CWE-079/EmailXss.expected rename to python/ql/test/experimental/query-tests/Security/CWE-079/ReflectedXSS.expected index 02fed5424cc..7f16b6dcdac 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-079/EmailXss.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-079/ReflectedXSS.expected @@ -12,8 +12,7 @@ edges | sendgrid_mail.py:1:19:1:25 | GSSA Variable request | sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | | sendgrid_mail.py:1:19:1:25 | GSSA Variable request | sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | | sendgrid_mail.py:14:22:14:28 | ControlFlowNode for request | sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | -| sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | sendgrid_mail.py:26:34:26:61 | ControlFlowNode for Subscript | -| sendgrid_mail.py:26:34:26:61 | ControlFlowNode for Subscript | sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | +| sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | | sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | ControlFlowNode for ImportMember | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | GSSA Variable request | | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | GSSA Variable request | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | @@ -53,7 +52,6 @@ nodes | sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | semmle.label | ControlFlowNode for HtmlContent() | | sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| sendgrid_mail.py:26:34:26:61 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/ReflectedXSS.qlref b/python/ql/test/experimental/query-tests/Security/CWE-079/ReflectedXSS.qlref new file mode 100644 index 00000000000..dec87309b29 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-079/ReflectedXSS.qlref @@ -0,0 +1 @@ +experimental/Security/CWE-079/ReflectedXSS.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.expected index 63d5e8ad821..564398c25c3 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.expected @@ -1,6 +1,27 @@ edges +| TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | ControlFlowNode for ImportMember | TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | GSSA Variable request | +| TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | GSSA Variable request | TimingAttackAgainstSensitiveInfo.py:14:8:14:14 | ControlFlowNode for request | +| TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | GSSA Variable request | TimingAttackAgainstSensitiveInfo.py:15:20:15:26 | ControlFlowNode for request | +| TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | GSSA Variable request | TimingAttackAgainstSensitiveInfo.py:20:8:20:14 | ControlFlowNode for request | +| TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | GSSA Variable request | TimingAttackAgainstSensitiveInfo.py:21:20:21:26 | ControlFlowNode for request | +| TimingAttackAgainstSensitiveInfo.py:14:8:14:14 | ControlFlowNode for request | TimingAttackAgainstSensitiveInfo.py:15:9:15:16 | SSA variable password | +| TimingAttackAgainstSensitiveInfo.py:15:9:15:16 | SSA variable password | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | +| TimingAttackAgainstSensitiveInfo.py:15:20:15:26 | ControlFlowNode for request | TimingAttackAgainstSensitiveInfo.py:15:9:15:16 | SSA variable password | +| TimingAttackAgainstSensitiveInfo.py:20:8:20:14 | ControlFlowNode for request | TimingAttackAgainstSensitiveInfo.py:21:9:21:16 | SSA variable password | +| TimingAttackAgainstSensitiveInfo.py:21:9:21:16 | SSA variable password | TimingAttackAgainstSensitiveInfo.py:22:38:22:45 | ControlFlowNode for password | +| TimingAttackAgainstSensitiveInfo.py:21:20:21:26 | ControlFlowNode for request | TimingAttackAgainstSensitiveInfo.py:21:9:21:16 | SSA variable password | nodes +| TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | GSSA Variable request | semmle.label | GSSA Variable request | +| TimingAttackAgainstSensitiveInfo.py:14:8:14:14 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| TimingAttackAgainstSensitiveInfo.py:15:9:15:16 | SSA variable password | semmle.label | SSA variable password | +| TimingAttackAgainstSensitiveInfo.py:15:20:15:26 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | +| TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | +| TimingAttackAgainstSensitiveInfo.py:20:8:20:14 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| TimingAttackAgainstSensitiveInfo.py:21:9:21:16 | SSA variable password | semmle.label | SSA variable password | +| TimingAttackAgainstSensitiveInfo.py:21:20:21:26 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| TimingAttackAgainstSensitiveInfo.py:22:38:22:45 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | subpaths #select | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | Timing attack against $@ validation. | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | client-supplied token | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-522-global-option/LdapInsecureAuth.expected b/python/ql/test/experimental/query-tests/Security/CWE-522-global-option/LDAPInsecureAuth.expected similarity index 100% rename from python/ql/test/experimental/query-tests/Security/CWE-522-global-option/LdapInsecureAuth.expected rename to python/ql/test/experimental/query-tests/Security/CWE-522-global-option/LDAPInsecureAuth.expected diff --git a/python/ql/test/experimental/query-tests/Security/CWE-522-global-option/LDAPInsecureAuth.qlref b/python/ql/test/experimental/query-tests/Security/CWE-522-global-option/LDAPInsecureAuth.qlref new file mode 100644 index 00000000000..8bb2c1e9b52 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-522-global-option/LDAPInsecureAuth.qlref @@ -0,0 +1 @@ +experimental/Security/CWE-522/LDAPInsecureAuth.ql \ No newline at end of file diff --git a/python/ql/test/experimental/query-tests/Security/CWE-522-global-option/LdapInsecureAuth.qlref b/python/ql/test/experimental/query-tests/Security/CWE-522-global-option/LdapInsecureAuth.qlref deleted file mode 100644 index 7b867cb3186..00000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-522-global-option/LdapInsecureAuth.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security/CWE-522/LdapInsecureAuth.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-522/LdapInsecureAuth.expected b/python/ql/test/experimental/query-tests/Security/CWE-522/LDAPInsecureAuth.expected similarity index 100% rename from python/ql/test/experimental/query-tests/Security/CWE-522/LdapInsecureAuth.expected rename to python/ql/test/experimental/query-tests/Security/CWE-522/LDAPInsecureAuth.expected diff --git a/python/ql/test/experimental/query-tests/Security/CWE-522/LDAPInsecureAuth.qlref b/python/ql/test/experimental/query-tests/Security/CWE-522/LDAPInsecureAuth.qlref new file mode 100644 index 00000000000..8bb2c1e9b52 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-522/LDAPInsecureAuth.qlref @@ -0,0 +1 @@ +experimental/Security/CWE-522/LDAPInsecureAuth.ql \ No newline at end of file diff --git a/python/ql/test/experimental/query-tests/Security/CWE-522/LdapInsecureAuth.qlref b/python/ql/test/experimental/query-tests/Security/CWE-522/LdapInsecureAuth.qlref deleted file mode 100644 index 7b867cb3186..00000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-522/LdapInsecureAuth.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security/CWE-522/LdapInsecureAuth.ql diff --git a/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.ql b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.ql index eaf935d573b..97a01fd4b5f 100644 --- a/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.ql +++ b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.ql @@ -8,7 +8,7 @@ module ModificationOfParameterWithDefaultTest implements TestSig { string getARelevantTag() { result = "modification" } private predicate relevant_node(DataFlow::Node sink) { - ModificationOfParameterWithDefault::Flow::flowTo(sink) + exists(ModificationOfParameterWithDefault::Configuration cfg | cfg.hasFlowTo(sink)) } predicate hasActualResult(Location location, string element, string tag, string value) { diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.ql b/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.ql index 90761391ce7..91ba1765724 100644 --- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.ql +++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.ql @@ -1,4 +1,4 @@ import python import experimental.dataflow.TestUtil.DataflowQueryTest import semmle.python.security.dataflow.PathInjectionQuery -import FromTaintTrackingStateConfig +import FromLegacyConfiguration diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected b/python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected index b8bcf46ec1e..b0df9a02cc0 100644 --- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected @@ -53,8 +53,7 @@ edges | path_injection.py:84:16:84:22 | ControlFlowNode for request | path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | | path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | path_injection.py:84:16:84:47 | ControlFlowNode for Attribute() | | path_injection.py:84:16:84:47 | ControlFlowNode for Attribute() | path_injection.py:84:5:84:12 | SSA variable filename | -| path_injection.py:85:5:85:24 | SSA variable possibly_unsafe_path | path_injection.py:86:24:86:43 | ControlFlowNode for possibly_unsafe_path | -| path_injection.py:86:24:86:43 | ControlFlowNode for possibly_unsafe_path | path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | +| path_injection.py:85:5:85:24 | SSA variable possibly_unsafe_path | path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | | path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | path_injection.py:93:5:93:8 | SSA variable path | | path_injection.py:93:5:93:8 | SSA variable path | path_injection.py:94:14:94:17 | ControlFlowNode for path | | path_injection.py:98:20:98:22 | ControlFlowNode for foo | path_injection.py:101:5:101:8 | SSA variable path | @@ -79,8 +78,7 @@ edges | path_injection.py:138:16:138:22 | ControlFlowNode for request | path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | | path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | path_injection.py:138:16:138:47 | ControlFlowNode for Attribute() | | path_injection.py:138:16:138:47 | ControlFlowNode for Attribute() | path_injection.py:138:5:138:12 | SSA variable filename | -| path_injection.py:139:5:139:8 | SSA variable path | path_injection.py:140:47:140:50 | ControlFlowNode for path | -| path_injection.py:140:47:140:50 | ControlFlowNode for path | path_injection.py:142:14:142:17 | ControlFlowNode for path | +| path_injection.py:139:5:139:8 | SSA variable path | path_injection.py:142:14:142:17 | ControlFlowNode for path | | path_injection.py:149:5:149:12 | SSA variable filename | path_injection.py:151:9:151:12 | SSA variable path | | path_injection.py:149:16:149:22 | ControlFlowNode for request | path_injection.py:149:16:149:27 | ControlFlowNode for Attribute | | path_injection.py:149:16:149:27 | ControlFlowNode for Attribute | path_injection.py:149:16:149:47 | ControlFlowNode for Attribute() | @@ -173,7 +171,6 @@ nodes | path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | path_injection.py:84:16:84:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | path_injection.py:85:5:85:24 | SSA variable possibly_unsafe_path | semmle.label | SSA variable possibly_unsafe_path | -| path_injection.py:86:24:86:43 | ControlFlowNode for possibly_unsafe_path | semmle.label | ControlFlowNode for possibly_unsafe_path | | path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | semmle.label | ControlFlowNode for possibly_unsafe_path | | path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | semmle.label | ControlFlowNode for foo_id | | path_injection.py:93:5:93:8 | SSA variable path | semmle.label | SSA variable path | @@ -205,7 +202,6 @@ nodes | path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | path_injection.py:138:16:138:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | path_injection.py:139:5:139:8 | SSA variable path | semmle.label | SSA variable path | -| path_injection.py:140:47:140:50 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | | path_injection.py:142:14:142:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | | path_injection.py:149:5:149:12 | SSA variable filename | semmle.label | SSA variable filename | | path_injection.py:149:16:149:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.ql b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.ql index df745b4ee8c..ecb787218b1 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.ql +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.ql @@ -1,4 +1,4 @@ import python import experimental.dataflow.TestUtil.DataflowQueryTest import semmle.python.security.dataflow.CommandInjectionQuery -import FromTaintTrackingConfig +import FromLegacyConfiguration diff --git a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.ql b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.ql index b2602b2b25c..b00d364b853 100644 --- a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.ql +++ b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.ql @@ -1,4 +1,4 @@ import python import experimental.dataflow.TestUtil.DataflowQueryTest import semmle.python.security.dataflow.UnsafeShellCommandConstructionQuery -import FromTaintTrackingConfig +import FromLegacyConfiguration diff --git a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.expected b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.expected index 90b58f8e319..5cc3f3eef6d 100644 --- a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.expected +++ b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.expected @@ -1,7 +1,6 @@ edges | test.py:23:25:23:25 | SSA variable e | test.py:24:16:24:16 | ControlFlowNode for e | -| test.py:31:25:31:25 | SSA variable e | test.py:32:16:32:16 | ControlFlowNode for e | -| test.py:32:16:32:16 | ControlFlowNode for e | test.py:32:16:32:30 | ControlFlowNode for Attribute | +| test.py:31:25:31:25 | SSA variable e | test.py:32:16:32:30 | ControlFlowNode for Attribute | | test.py:49:9:49:11 | SSA variable err | test.py:50:29:50:31 | ControlFlowNode for err | | test.py:49:15:49:36 | ControlFlowNode for Attribute() | test.py:49:9:49:11 | SSA variable err | | test.py:50:29:50:31 | ControlFlowNode for err | test.py:50:16:50:32 | ControlFlowNode for format_error() | @@ -13,7 +12,6 @@ nodes | test.py:23:25:23:25 | SSA variable e | semmle.label | SSA variable e | | test.py:24:16:24:16 | ControlFlowNode for e | semmle.label | ControlFlowNode for e | | test.py:31:25:31:25 | SSA variable e | semmle.label | SSA variable e | -| test.py:32:16:32:16 | ControlFlowNode for e | semmle.label | ControlFlowNode for e | | test.py:32:16:32:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:49:9:49:11 | SSA variable err | semmle.label | SSA variable err | | test.py:49:15:49:36 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | diff --git a/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/PamAuthorization.expected b/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/PamAuthorization.expected index 9379464e1c1..f259cfab561 100644 --- a/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/PamAuthorization.expected +++ b/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/PamAuthorization.expected @@ -1,13 +1,10 @@ edges | pam_test.py:4:26:4:32 | ControlFlowNode for ImportMember | pam_test.py:4:26:4:32 | GSSA Variable request | | pam_test.py:4:26:4:32 | GSSA Variable request | pam_test.py:71:16:71:22 | ControlFlowNode for request | -| pam_test.py:71:5:71:12 | SSA variable username | pam_test.py:74:33:74:40 | ControlFlowNode for username | +| pam_test.py:71:5:71:12 | SSA variable username | pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() | | pam_test.py:71:16:71:22 | ControlFlowNode for request | pam_test.py:71:16:71:27 | ControlFlowNode for Attribute | | pam_test.py:71:16:71:27 | ControlFlowNode for Attribute | pam_test.py:71:16:71:47 | ControlFlowNode for Attribute() | | pam_test.py:71:16:71:47 | ControlFlowNode for Attribute() | pam_test.py:71:5:71:12 | SSA variable username | -| pam_test.py:74:33:74:40 | ControlFlowNode for username | pam_test.py:74:62:74:67 | ControlFlowNode for handle | -| pam_test.py:74:62:74:67 | ControlFlowNode for handle | pam_test.py:76:31:76:36 | ControlFlowNode for handle | -| pam_test.py:76:31:76:36 | ControlFlowNode for handle | pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() | nodes | pam_test.py:4:26:4:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | pam_test.py:4:26:4:32 | GSSA Variable request | semmle.label | GSSA Variable request | @@ -15,10 +12,7 @@ nodes | pam_test.py:71:16:71:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | pam_test.py:71:16:71:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | pam_test.py:71:16:71:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| pam_test.py:74:33:74:40 | ControlFlowNode for username | semmle.label | ControlFlowNode for username | -| pam_test.py:74:62:74:67 | ControlFlowNode for handle | semmle.label | ControlFlowNode for handle | | pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() | semmle.label | ControlFlowNode for pam_authenticate() | -| pam_test.py:76:31:76:36 | ControlFlowNode for handle | semmle.label | ControlFlowNode for handle | subpaths #select | pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() | pam_test.py:4:26:4:32 | ControlFlowNode for ImportMember | pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() | This PAM authentication depends on a $@, and 'pam_acct_mgmt' is not called afterwards. | pam_test.py:4:26:4:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/WeakSensitiveDataHashing.expected b/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/WeakSensitiveDataHashing.expected index 6be594dae63..30a04916e7f 100644 --- a/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/WeakSensitiveDataHashing.expected +++ b/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/WeakSensitiveDataHashing.expected @@ -5,13 +5,13 @@ edges | test_cryptodome.py:2:37:2:51 | ControlFlowNode for ImportMember | test_cryptodome.py:2:37:2:51 | GSSA Variable get_certificate | | test_cryptodome.py:2:37:2:51 | GSSA Variable get_certificate | test_cryptodome.py:6:17:6:31 | ControlFlowNode for get_certificate | | test_cryptodome.py:6:5:6:13 | SSA variable dangerous | test_cryptodome.py:8:19:8:27 | ControlFlowNode for dangerous | -| test_cryptodome.py:6:17:6:31 | ControlFlowNode for get_certificate | test_cryptodome.py:6:17:6:33 | ControlFlowNode for get_certificate() | +| test_cryptodome.py:6:17:6:31 | ControlFlowNode for get_certificate | test_cryptodome.py:6:5:6:13 | SSA variable dangerous | | test_cryptodome.py:6:17:6:33 | ControlFlowNode for get_certificate() | test_cryptodome.py:6:5:6:13 | SSA variable dangerous | | test_cryptodome.py:13:5:13:13 | SSA variable dangerous | test_cryptodome.py:15:19:15:27 | ControlFlowNode for dangerous | -| test_cryptodome.py:13:17:13:28 | ControlFlowNode for get_password | test_cryptodome.py:13:17:13:30 | ControlFlowNode for get_password() | +| test_cryptodome.py:13:17:13:28 | ControlFlowNode for get_password | test_cryptodome.py:13:5:13:13 | SSA variable dangerous | | test_cryptodome.py:13:17:13:30 | ControlFlowNode for get_password() | test_cryptodome.py:13:5:13:13 | SSA variable dangerous | | test_cryptodome.py:20:5:20:13 | SSA variable dangerous | test_cryptodome.py:24:19:24:27 | ControlFlowNode for dangerous | -| test_cryptodome.py:20:17:20:28 | ControlFlowNode for get_password | test_cryptodome.py:20:17:20:30 | ControlFlowNode for get_password() | +| test_cryptodome.py:20:17:20:28 | ControlFlowNode for get_password | test_cryptodome.py:20:5:20:13 | SSA variable dangerous | | test_cryptodome.py:20:17:20:30 | ControlFlowNode for get_password() | test_cryptodome.py:20:5:20:13 | SSA variable dangerous | | test_cryptography.py:3:23:3:34 | ControlFlowNode for ImportMember | test_cryptography.py:3:23:3:34 | GSSA Variable get_password | | test_cryptography.py:3:23:3:34 | GSSA Variable get_password | test_cryptography.py:15:17:15:28 | ControlFlowNode for get_password | @@ -19,13 +19,13 @@ edges | test_cryptography.py:3:37:3:51 | ControlFlowNode for ImportMember | test_cryptography.py:3:37:3:51 | GSSA Variable get_certificate | | test_cryptography.py:3:37:3:51 | GSSA Variable get_certificate | test_cryptography.py:7:17:7:31 | ControlFlowNode for get_certificate | | test_cryptography.py:7:5:7:13 | SSA variable dangerous | test_cryptography.py:9:19:9:27 | ControlFlowNode for dangerous | -| test_cryptography.py:7:17:7:31 | ControlFlowNode for get_certificate | test_cryptography.py:7:17:7:33 | ControlFlowNode for get_certificate() | +| test_cryptography.py:7:17:7:31 | ControlFlowNode for get_certificate | test_cryptography.py:7:5:7:13 | SSA variable dangerous | | test_cryptography.py:7:17:7:33 | ControlFlowNode for get_certificate() | test_cryptography.py:7:5:7:13 | SSA variable dangerous | | test_cryptography.py:15:5:15:13 | SSA variable dangerous | test_cryptography.py:17:19:17:27 | ControlFlowNode for dangerous | -| test_cryptography.py:15:17:15:28 | ControlFlowNode for get_password | test_cryptography.py:15:17:15:30 | ControlFlowNode for get_password() | +| test_cryptography.py:15:17:15:28 | ControlFlowNode for get_password | test_cryptography.py:15:5:15:13 | SSA variable dangerous | | test_cryptography.py:15:17:15:30 | ControlFlowNode for get_password() | test_cryptography.py:15:5:15:13 | SSA variable dangerous | | test_cryptography.py:23:5:23:13 | SSA variable dangerous | test_cryptography.py:27:19:27:27 | ControlFlowNode for dangerous | -| test_cryptography.py:23:17:23:28 | ControlFlowNode for get_password | test_cryptography.py:23:17:23:30 | ControlFlowNode for get_password() | +| test_cryptography.py:23:17:23:28 | ControlFlowNode for get_password | test_cryptography.py:23:5:23:13 | SSA variable dangerous | | test_cryptography.py:23:17:23:30 | ControlFlowNode for get_password() | test_cryptography.py:23:5:23:13 | SSA variable dangerous | nodes | test_cryptodome.py:2:23:2:34 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | diff --git a/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/FullServerSideRequestForgery.expected b/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/FullServerSideRequestForgery.expected index 3db6c82b96c..a5c9c706518 100644 --- a/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/FullServerSideRequestForgery.expected +++ b/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/FullServerSideRequestForgery.expected @@ -1,110 +1,306 @@ edges | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:1:19:1:25 | GSSA Variable request | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:1:19:1:25 | GSSA Variable request | | full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:8:17:8:23 | ControlFlowNode for request | | full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:38:17:38:23 | ControlFlowNode for request | | full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:58:17:58:23 | ControlFlowNode for request | | full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:72:17:72:23 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:86:18:86:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:92:18:92:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:98:18:98:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:104:18:104:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:110:18:110:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:119:18:119:24 | ControlFlowNode for request | +| full_partial_test.py:7:5:7:14 | SSA variable user_input | full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input | | full_partial_test.py:7:5:7:14 | SSA variable user_input | full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input | | full_partial_test.py:7:5:7:14 | SSA variable user_input | full_partial_test.py:12:5:12:7 | SSA variable url | +| full_partial_test.py:7:5:7:14 | SSA variable user_input | full_partial_test.py:12:5:12:7 | SSA variable url | +| full_partial_test.py:7:5:7:14 | SSA variable user_input | full_partial_test.py:18:5:18:7 | SSA variable url | | full_partial_test.py:7:5:7:14 | SSA variable user_input | full_partial_test.py:18:5:18:7 | SSA variable url | | full_partial_test.py:7:5:7:14 | SSA variable user_input | full_partial_test.py:22:5:22:7 | SSA variable url | +| full_partial_test.py:7:5:7:14 | SSA variable user_input | full_partial_test.py:22:5:22:7 | SSA variable url | | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:7:5:7:14 | SSA variable user_input | +| full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:7:5:7:14 | SSA variable user_input | +| full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:8:5:8:13 | SSA variable query_val | +| full_partial_test.py:8:5:8:13 | SSA variable query_val | full_partial_test.py:22:5:22:7 | SSA variable url | +| full_partial_test.py:8:17:8:23 | ControlFlowNode for request | full_partial_test.py:8:5:8:13 | SSA variable query_val | +| full_partial_test.py:12:5:12:7 | SSA variable url | full_partial_test.py:13:18:13:20 | ControlFlowNode for url | | full_partial_test.py:12:5:12:7 | SSA variable url | full_partial_test.py:13:18:13:20 | ControlFlowNode for url | | full_partial_test.py:18:5:18:7 | SSA variable url | full_partial_test.py:19:18:19:20 | ControlFlowNode for url | +| full_partial_test.py:18:5:18:7 | SSA variable url | full_partial_test.py:19:18:19:20 | ControlFlowNode for url | +| full_partial_test.py:22:5:22:7 | SSA variable url | full_partial_test.py:23:18:23:20 | ControlFlowNode for url | | full_partial_test.py:22:5:22:7 | SSA variable url | full_partial_test.py:23:18:23:20 | ControlFlowNode for url | | full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:41:5:41:7 | SSA variable url | +| full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:41:5:41:7 | SSA variable url | +| full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:44:5:44:7 | SSA variable url | | full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:44:5:44:7 | SSA variable url | | full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:47:5:47:7 | SSA variable url | +| full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:47:5:47:7 | SSA variable url | +| full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:50:5:50:7 | SSA variable url | | full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:50:5:50:7 | SSA variable url | | full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:53:5:53:7 | SSA variable url | +| full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:53:5:53:7 | SSA variable url | | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | full_partial_test.py:37:5:37:14 | SSA variable user_input | +| full_partial_test.py:37:18:37:24 | ControlFlowNode for request | full_partial_test.py:37:5:37:14 | SSA variable user_input | +| full_partial_test.py:37:18:37:24 | ControlFlowNode for request | full_partial_test.py:38:5:38:13 | SSA variable query_val | +| full_partial_test.py:38:5:38:13 | SSA variable query_val | full_partial_test.py:47:5:47:7 | SSA variable url | +| full_partial_test.py:38:17:38:23 | ControlFlowNode for request | full_partial_test.py:38:5:38:13 | SSA variable query_val | +| full_partial_test.py:41:5:41:7 | SSA variable url | full_partial_test.py:42:18:42:20 | ControlFlowNode for url | | full_partial_test.py:41:5:41:7 | SSA variable url | full_partial_test.py:42:18:42:20 | ControlFlowNode for url | | full_partial_test.py:44:5:44:7 | SSA variable url | full_partial_test.py:45:18:45:20 | ControlFlowNode for url | +| full_partial_test.py:44:5:44:7 | SSA variable url | full_partial_test.py:45:18:45:20 | ControlFlowNode for url | +| full_partial_test.py:47:5:47:7 | SSA variable url | full_partial_test.py:48:18:48:20 | ControlFlowNode for url | | full_partial_test.py:47:5:47:7 | SSA variable url | full_partial_test.py:48:18:48:20 | ControlFlowNode for url | | full_partial_test.py:50:5:50:7 | SSA variable url | full_partial_test.py:51:18:51:20 | ControlFlowNode for url | +| full_partial_test.py:50:5:50:7 | SSA variable url | full_partial_test.py:51:18:51:20 | ControlFlowNode for url | +| full_partial_test.py:53:5:53:7 | SSA variable url | full_partial_test.py:54:18:54:20 | ControlFlowNode for url | | full_partial_test.py:53:5:53:7 | SSA variable url | full_partial_test.py:54:18:54:20 | ControlFlowNode for url | | full_partial_test.py:57:5:57:14 | SSA variable user_input | full_partial_test.py:61:5:61:7 | SSA variable url | +| full_partial_test.py:57:5:57:14 | SSA variable user_input | full_partial_test.py:61:5:61:7 | SSA variable url | | full_partial_test.py:57:5:57:14 | SSA variable user_input | full_partial_test.py:64:5:64:7 | SSA variable url | +| full_partial_test.py:57:5:57:14 | SSA variable user_input | full_partial_test.py:64:5:64:7 | SSA variable url | +| full_partial_test.py:57:5:57:14 | SSA variable user_input | full_partial_test.py:67:5:67:7 | SSA variable url | | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | full_partial_test.py:57:5:57:14 | SSA variable user_input | +| full_partial_test.py:57:18:57:24 | ControlFlowNode for request | full_partial_test.py:57:5:57:14 | SSA variable user_input | +| full_partial_test.py:57:18:57:24 | ControlFlowNode for request | full_partial_test.py:58:5:58:13 | SSA variable query_val | +| full_partial_test.py:58:5:58:13 | SSA variable query_val | full_partial_test.py:67:5:67:7 | SSA variable url | +| full_partial_test.py:58:17:58:23 | ControlFlowNode for request | full_partial_test.py:58:5:58:13 | SSA variable query_val | +| full_partial_test.py:61:5:61:7 | SSA variable url | full_partial_test.py:62:18:62:20 | ControlFlowNode for url | | full_partial_test.py:61:5:61:7 | SSA variable url | full_partial_test.py:62:18:62:20 | ControlFlowNode for url | | full_partial_test.py:64:5:64:7 | SSA variable url | full_partial_test.py:65:18:65:20 | ControlFlowNode for url | +| full_partial_test.py:64:5:64:7 | SSA variable url | full_partial_test.py:65:18:65:20 | ControlFlowNode for url | +| full_partial_test.py:67:5:67:7 | SSA variable url | full_partial_test.py:68:18:68:20 | ControlFlowNode for url | +| full_partial_test.py:71:5:71:14 | SSA variable user_input | full_partial_test.py:75:5:75:7 | SSA variable url | | full_partial_test.py:71:5:71:14 | SSA variable user_input | full_partial_test.py:75:5:75:7 | SSA variable url | | full_partial_test.py:71:5:71:14 | SSA variable user_input | full_partial_test.py:78:5:78:7 | SSA variable url | +| full_partial_test.py:71:5:71:14 | SSA variable user_input | full_partial_test.py:78:5:78:7 | SSA variable url | +| full_partial_test.py:71:5:71:14 | SSA variable user_input | full_partial_test.py:81:5:81:7 | SSA variable url | | full_partial_test.py:71:5:71:14 | SSA variable user_input | full_partial_test.py:81:5:81:7 | SSA variable url | | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | full_partial_test.py:71:5:71:14 | SSA variable user_input | +| full_partial_test.py:71:18:71:24 | ControlFlowNode for request | full_partial_test.py:71:5:71:14 | SSA variable user_input | +| full_partial_test.py:71:18:71:24 | ControlFlowNode for request | full_partial_test.py:72:5:72:13 | SSA variable query_val | +| full_partial_test.py:72:5:72:13 | SSA variable query_val | full_partial_test.py:81:5:81:7 | SSA variable url | +| full_partial_test.py:72:17:72:23 | ControlFlowNode for request | full_partial_test.py:72:5:72:13 | SSA variable query_val | +| full_partial_test.py:75:5:75:7 | SSA variable url | full_partial_test.py:76:18:76:20 | ControlFlowNode for url | | full_partial_test.py:75:5:75:7 | SSA variable url | full_partial_test.py:76:18:76:20 | ControlFlowNode for url | | full_partial_test.py:78:5:78:7 | SSA variable url | full_partial_test.py:79:18:79:20 | ControlFlowNode for url | +| full_partial_test.py:78:5:78:7 | SSA variable url | full_partial_test.py:79:18:79:20 | ControlFlowNode for url | | full_partial_test.py:81:5:81:7 | SSA variable url | full_partial_test.py:82:18:82:20 | ControlFlowNode for url | +| full_partial_test.py:81:5:81:7 | SSA variable url | full_partial_test.py:82:18:82:20 | ControlFlowNode for url | +| full_partial_test.py:86:5:86:14 | SSA variable user_input | full_partial_test.py:88:5:88:7 | SSA variable url | +| full_partial_test.py:86:18:86:24 | ControlFlowNode for request | full_partial_test.py:86:5:86:14 | SSA variable user_input | +| full_partial_test.py:88:5:88:7 | SSA variable url | full_partial_test.py:89:18:89:20 | ControlFlowNode for url | +| full_partial_test.py:92:5:92:14 | SSA variable user_input | full_partial_test.py:94:5:94:7 | SSA variable url | +| full_partial_test.py:92:18:92:24 | ControlFlowNode for request | full_partial_test.py:92:5:92:14 | SSA variable user_input | +| full_partial_test.py:94:5:94:7 | SSA variable url | full_partial_test.py:95:18:95:20 | ControlFlowNode for url | +| full_partial_test.py:98:5:98:14 | SSA variable user_input | full_partial_test.py:100:5:100:7 | SSA variable url | +| full_partial_test.py:98:18:98:24 | ControlFlowNode for request | full_partial_test.py:98:5:98:14 | SSA variable user_input | +| full_partial_test.py:100:5:100:7 | SSA variable url | full_partial_test.py:101:18:101:20 | ControlFlowNode for url | +| full_partial_test.py:104:5:104:14 | SSA variable user_input | full_partial_test.py:106:5:106:7 | SSA variable url | +| full_partial_test.py:104:18:104:24 | ControlFlowNode for request | full_partial_test.py:104:5:104:14 | SSA variable user_input | +| full_partial_test.py:106:5:106:7 | SSA variable url | full_partial_test.py:107:18:107:20 | ControlFlowNode for url | +| full_partial_test.py:110:5:110:14 | SSA variable user_input | full_partial_test.py:115:5:115:7 | SSA variable url | +| full_partial_test.py:110:18:110:24 | ControlFlowNode for request | full_partial_test.py:110:5:110:14 | SSA variable user_input | +| full_partial_test.py:115:5:115:7 | SSA variable url | full_partial_test.py:116:18:116:20 | ControlFlowNode for url | +| full_partial_test.py:119:5:119:14 | SSA variable user_input | full_partial_test.py:121:5:121:7 | SSA variable url | +| full_partial_test.py:119:18:119:24 | ControlFlowNode for request | full_partial_test.py:119:5:119:14 | SSA variable user_input | +| full_partial_test.py:121:5:121:7 | SSA variable url | full_partial_test.py:122:18:122:20 | ControlFlowNode for url | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:1:26:1:32 | GSSA Variable request | | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:1:26:1:32 | GSSA Variable request | | test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:9:19:9:25 | ControlFlowNode for request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:9:19:9:25 | ControlFlowNode for request | | test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:10:19:10:25 | ControlFlowNode for request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:10:19:10:25 | ControlFlowNode for request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:11:18:11:24 | ControlFlowNode for request | +| test_http_client.py:9:5:9:15 | SSA variable unsafe_host | test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | | test_http_client.py:9:5:9:15 | SSA variable unsafe_host | test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | | test_http_client.py:9:5:9:15 | SSA variable unsafe_host | test_http_client.py:18:27:18:37 | ControlFlowNode for unsafe_host | +| test_http_client.py:9:5:9:15 | SSA variable unsafe_host | test_http_client.py:18:27:18:37 | ControlFlowNode for unsafe_host | +| test_http_client.py:9:5:9:15 | SSA variable unsafe_host | test_http_client.py:25:27:25:37 | ControlFlowNode for unsafe_host | | test_http_client.py:9:5:9:15 | SSA variable unsafe_host | test_http_client.py:25:27:25:37 | ControlFlowNode for unsafe_host | | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:9:5:9:15 | SSA variable unsafe_host | +| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:9:5:9:15 | SSA variable unsafe_host | | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:10:5:10:15 | SSA variable unsafe_path | +| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:10:5:10:15 | SSA variable unsafe_path | +| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:11:5:11:14 | SSA variable user_input | +| test_http_client.py:10:5:10:15 | SSA variable unsafe_path | test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | | test_http_client.py:10:5:10:15 | SSA variable unsafe_path | test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | | test_http_client.py:10:5:10:15 | SSA variable unsafe_path | test_http_client.py:19:25:19:35 | ControlFlowNode for unsafe_path | +| test_http_client.py:10:5:10:15 | SSA variable unsafe_path | test_http_client.py:19:25:19:35 | ControlFlowNode for unsafe_path | +| test_http_client.py:10:5:10:15 | SSA variable unsafe_path | test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_path | | test_http_client.py:10:5:10:15 | SSA variable unsafe_path | test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_path | | test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:10:5:10:15 | SSA variable unsafe_path | +| test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:10:5:10:15 | SSA variable unsafe_path | +| test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:11:5:11:14 | SSA variable user_input | +| test_http_client.py:11:5:11:14 | SSA variable user_input | test_http_client.py:31:5:31:8 | SSA variable path | +| test_http_client.py:11:5:11:14 | SSA variable user_input | test_http_client.py:35:5:35:8 | SSA variable path | +| test_http_client.py:11:18:11:24 | ControlFlowNode for request | test_http_client.py:11:5:11:14 | SSA variable user_input | +| test_http_client.py:31:5:31:8 | SSA variable path | test_http_client.py:33:25:33:28 | ControlFlowNode for path | +| test_http_client.py:35:5:35:8 | SSA variable path | test_http_client.py:37:25:37:28 | ControlFlowNode for path | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | test_requests.py:1:19:1:25 | GSSA Variable request | | test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | test_requests.py:1:19:1:25 | GSSA Variable request | | test_requests.py:1:19:1:25 | GSSA Variable request | test_requests.py:6:18:6:24 | ControlFlowNode for request | +| test_requests.py:1:19:1:25 | GSSA Variable request | test_requests.py:6:18:6:24 | ControlFlowNode for request | | test_requests.py:6:5:6:14 | SSA variable user_input | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | +| test_requests.py:6:5:6:14 | SSA variable user_input | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | +| test_requests.py:6:18:6:24 | ControlFlowNode for request | test_requests.py:6:5:6:14 | SSA variable user_input | | test_requests.py:6:18:6:24 | ControlFlowNode for request | test_requests.py:6:5:6:14 | SSA variable user_input | nodes | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | full_partial_test.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | full_partial_test.py:7:5:7:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| full_partial_test.py:7:5:7:14 | SSA variable user_input | semmle.label | SSA variable user_input | | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:7:18:7:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:8:5:8:13 | SSA variable query_val | semmle.label | SSA variable query_val | +| full_partial_test.py:8:17:8:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | | full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | | full_partial_test.py:12:5:12:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:12:5:12:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:13:18:13:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:13:18:13:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:18:5:18:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:18:5:18:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:19:18:19:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:19:18:19:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:22:5:22:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:22:5:22:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:23:18:23:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:23:18:23:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:37:5:37:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| full_partial_test.py:37:5:37:14 | SSA variable user_input | semmle.label | SSA variable user_input | | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:37:18:37:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:38:5:38:13 | SSA variable query_val | semmle.label | SSA variable query_val | +| full_partial_test.py:38:17:38:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:41:5:41:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:41:5:41:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:42:18:42:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:42:18:42:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:44:5:44:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:44:5:44:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:45:18:45:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:45:18:45:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:47:5:47:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:47:5:47:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:48:18:48:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:48:18:48:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:50:5:50:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:50:5:50:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:51:18:51:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:51:18:51:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:53:5:53:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:53:5:53:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:54:18:54:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:54:18:54:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:57:5:57:14 | SSA variable user_input | semmle.label | SSA variable user_input | | full_partial_test.py:57:5:57:14 | SSA variable user_input | semmle.label | SSA variable user_input | | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:57:18:57:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:58:5:58:13 | SSA variable query_val | semmle.label | SSA variable query_val | +| full_partial_test.py:58:17:58:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:61:5:61:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:61:5:61:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:62:18:62:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:62:18:62:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:64:5:64:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:64:5:64:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:65:18:65:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:65:18:65:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:67:5:67:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:68:18:68:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:71:5:71:14 | SSA variable user_input | semmle.label | SSA variable user_input | | full_partial_test.py:71:5:71:14 | SSA variable user_input | semmle.label | SSA variable user_input | | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:71:18:71:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:72:5:72:13 | SSA variable query_val | semmle.label | SSA variable query_val | +| full_partial_test.py:72:17:72:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:75:5:75:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:75:5:75:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:76:18:76:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:76:18:76:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:78:5:78:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:78:5:78:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:79:18:79:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:79:18:79:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:81:5:81:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:81:5:81:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:82:18:82:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:82:18:82:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:86:5:86:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| full_partial_test.py:86:18:86:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:88:5:88:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:89:18:89:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:92:5:92:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| full_partial_test.py:92:18:92:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:94:5:94:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:95:18:95:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:98:5:98:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| full_partial_test.py:98:18:98:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:100:5:100:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:101:18:101:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:104:5:104:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| full_partial_test.py:104:18:104:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:106:5:106:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:107:18:107:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:110:5:110:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| full_partial_test.py:110:18:110:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:115:5:115:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:116:18:116:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:119:5:119:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| full_partial_test.py:119:18:119:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:121:5:121:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:122:18:122:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | test_http_client.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| test_http_client.py:9:5:9:15 | SSA variable unsafe_host | semmle.label | SSA variable unsafe_host | | test_http_client.py:9:5:9:15 | SSA variable unsafe_host | semmle.label | SSA variable unsafe_host | | test_http_client.py:9:19:9:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test_http_client.py:9:19:9:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test_http_client.py:10:5:10:15 | SSA variable unsafe_path | semmle.label | SSA variable unsafe_path | | test_http_client.py:10:5:10:15 | SSA variable unsafe_path | semmle.label | SSA variable unsafe_path | | test_http_client.py:10:19:10:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test_http_client.py:10:19:10:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test_http_client.py:11:5:11:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| test_http_client.py:11:18:11:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host | | test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host | | test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path | +| test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path | +| test_http_client.py:18:27:18:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host | | test_http_client.py:18:27:18:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host | | test_http_client.py:19:25:19:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path | +| test_http_client.py:19:25:19:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path | +| test_http_client.py:25:27:25:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host | | test_http_client.py:25:27:25:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host | | test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path | +| test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path | +| test_http_client.py:31:5:31:8 | SSA variable path | semmle.label | SSA variable path | +| test_http_client.py:33:25:33:28 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | +| test_http_client.py:35:5:35:8 | SSA variable path | semmle.label | SSA variable path | +| test_http_client.py:37:25:37:28 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | test_requests.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | +| test_requests.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | +| test_requests.py:6:5:6:14 | SSA variable user_input | semmle.label | SSA variable user_input | | test_requests.py:6:5:6:14 | SSA variable user_input | semmle.label | SSA variable user_input | | test_requests.py:6:18:6:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test_requests.py:6:18:6:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test_requests.py:8:18:8:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | subpaths #select diff --git a/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected b/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected index aa983e62e01..faa8560d19f 100644 --- a/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected +++ b/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected @@ -1,12 +1,17 @@ edges | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:1:19:1:25 | GSSA Variable request | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:1:19:1:25 | GSSA Variable request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | | full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | | full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:8:17:8:23 | ControlFlowNode for request | | full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | | full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:38:17:38:23 | ControlFlowNode for request | | full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | | full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:58:17:58:23 | ControlFlowNode for request | | full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | | full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:72:17:72:23 | ControlFlowNode for request | | full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:86:18:86:24 | ControlFlowNode for request | | full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:92:18:92:24 | ControlFlowNode for request | @@ -15,49 +20,80 @@ edges | full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:110:18:110:24 | ControlFlowNode for request | | full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:119:18:119:24 | ControlFlowNode for request | | full_partial_test.py:7:5:7:14 | SSA variable user_input | full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input | +| full_partial_test.py:7:5:7:14 | SSA variable user_input | full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input | +| full_partial_test.py:7:5:7:14 | SSA variable user_input | full_partial_test.py:12:5:12:7 | SSA variable url | | full_partial_test.py:7:5:7:14 | SSA variable user_input | full_partial_test.py:12:5:12:7 | SSA variable url | | full_partial_test.py:7:5:7:14 | SSA variable user_input | full_partial_test.py:18:5:18:7 | SSA variable url | +| full_partial_test.py:7:5:7:14 | SSA variable user_input | full_partial_test.py:18:5:18:7 | SSA variable url | | full_partial_test.py:7:5:7:14 | SSA variable user_input | full_partial_test.py:22:5:22:7 | SSA variable url | +| full_partial_test.py:7:5:7:14 | SSA variable user_input | full_partial_test.py:22:5:22:7 | SSA variable url | +| full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:7:5:7:14 | SSA variable user_input | | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:7:5:7:14 | SSA variable user_input | | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:8:5:8:13 | SSA variable query_val | | full_partial_test.py:8:5:8:13 | SSA variable query_val | full_partial_test.py:22:5:22:7 | SSA variable url | | full_partial_test.py:8:17:8:23 | ControlFlowNode for request | full_partial_test.py:8:5:8:13 | SSA variable query_val | | full_partial_test.py:12:5:12:7 | SSA variable url | full_partial_test.py:13:18:13:20 | ControlFlowNode for url | +| full_partial_test.py:12:5:12:7 | SSA variable url | full_partial_test.py:13:18:13:20 | ControlFlowNode for url | +| full_partial_test.py:18:5:18:7 | SSA variable url | full_partial_test.py:19:18:19:20 | ControlFlowNode for url | | full_partial_test.py:18:5:18:7 | SSA variable url | full_partial_test.py:19:18:19:20 | ControlFlowNode for url | | full_partial_test.py:22:5:22:7 | SSA variable url | full_partial_test.py:23:18:23:20 | ControlFlowNode for url | +| full_partial_test.py:22:5:22:7 | SSA variable url | full_partial_test.py:23:18:23:20 | ControlFlowNode for url | +| full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:41:5:41:7 | SSA variable url | | full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:41:5:41:7 | SSA variable url | | full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:44:5:44:7 | SSA variable url | +| full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:44:5:44:7 | SSA variable url | +| full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:47:5:47:7 | SSA variable url | | full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:47:5:47:7 | SSA variable url | | full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:50:5:50:7 | SSA variable url | +| full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:50:5:50:7 | SSA variable url | | full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:53:5:53:7 | SSA variable url | +| full_partial_test.py:37:5:37:14 | SSA variable user_input | full_partial_test.py:53:5:53:7 | SSA variable url | +| full_partial_test.py:37:18:37:24 | ControlFlowNode for request | full_partial_test.py:37:5:37:14 | SSA variable user_input | | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | full_partial_test.py:37:5:37:14 | SSA variable user_input | | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | full_partial_test.py:38:5:38:13 | SSA variable query_val | | full_partial_test.py:38:5:38:13 | SSA variable query_val | full_partial_test.py:47:5:47:7 | SSA variable url | | full_partial_test.py:38:17:38:23 | ControlFlowNode for request | full_partial_test.py:38:5:38:13 | SSA variable query_val | | full_partial_test.py:41:5:41:7 | SSA variable url | full_partial_test.py:42:18:42:20 | ControlFlowNode for url | +| full_partial_test.py:41:5:41:7 | SSA variable url | full_partial_test.py:42:18:42:20 | ControlFlowNode for url | +| full_partial_test.py:44:5:44:7 | SSA variable url | full_partial_test.py:45:18:45:20 | ControlFlowNode for url | | full_partial_test.py:44:5:44:7 | SSA variable url | full_partial_test.py:45:18:45:20 | ControlFlowNode for url | | full_partial_test.py:47:5:47:7 | SSA variable url | full_partial_test.py:48:18:48:20 | ControlFlowNode for url | +| full_partial_test.py:47:5:47:7 | SSA variable url | full_partial_test.py:48:18:48:20 | ControlFlowNode for url | +| full_partial_test.py:50:5:50:7 | SSA variable url | full_partial_test.py:51:18:51:20 | ControlFlowNode for url | | full_partial_test.py:50:5:50:7 | SSA variable url | full_partial_test.py:51:18:51:20 | ControlFlowNode for url | | full_partial_test.py:53:5:53:7 | SSA variable url | full_partial_test.py:54:18:54:20 | ControlFlowNode for url | +| full_partial_test.py:53:5:53:7 | SSA variable url | full_partial_test.py:54:18:54:20 | ControlFlowNode for url | +| full_partial_test.py:57:5:57:14 | SSA variable user_input | full_partial_test.py:61:5:61:7 | SSA variable url | | full_partial_test.py:57:5:57:14 | SSA variable user_input | full_partial_test.py:61:5:61:7 | SSA variable url | | full_partial_test.py:57:5:57:14 | SSA variable user_input | full_partial_test.py:64:5:64:7 | SSA variable url | +| full_partial_test.py:57:5:57:14 | SSA variable user_input | full_partial_test.py:64:5:64:7 | SSA variable url | | full_partial_test.py:57:5:57:14 | SSA variable user_input | full_partial_test.py:67:5:67:7 | SSA variable url | | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | full_partial_test.py:57:5:57:14 | SSA variable user_input | +| full_partial_test.py:57:18:57:24 | ControlFlowNode for request | full_partial_test.py:57:5:57:14 | SSA variable user_input | | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | full_partial_test.py:58:5:58:13 | SSA variable query_val | | full_partial_test.py:58:5:58:13 | SSA variable query_val | full_partial_test.py:67:5:67:7 | SSA variable url | | full_partial_test.py:58:17:58:23 | ControlFlowNode for request | full_partial_test.py:58:5:58:13 | SSA variable query_val | | full_partial_test.py:61:5:61:7 | SSA variable url | full_partial_test.py:62:18:62:20 | ControlFlowNode for url | +| full_partial_test.py:61:5:61:7 | SSA variable url | full_partial_test.py:62:18:62:20 | ControlFlowNode for url | +| full_partial_test.py:64:5:64:7 | SSA variable url | full_partial_test.py:65:18:65:20 | ControlFlowNode for url | | full_partial_test.py:64:5:64:7 | SSA variable url | full_partial_test.py:65:18:65:20 | ControlFlowNode for url | | full_partial_test.py:67:5:67:7 | SSA variable url | full_partial_test.py:68:18:68:20 | ControlFlowNode for url | | full_partial_test.py:71:5:71:14 | SSA variable user_input | full_partial_test.py:75:5:75:7 | SSA variable url | +| full_partial_test.py:71:5:71:14 | SSA variable user_input | full_partial_test.py:75:5:75:7 | SSA variable url | +| full_partial_test.py:71:5:71:14 | SSA variable user_input | full_partial_test.py:78:5:78:7 | SSA variable url | | full_partial_test.py:71:5:71:14 | SSA variable user_input | full_partial_test.py:78:5:78:7 | SSA variable url | | full_partial_test.py:71:5:71:14 | SSA variable user_input | full_partial_test.py:81:5:81:7 | SSA variable url | +| full_partial_test.py:71:5:71:14 | SSA variable user_input | full_partial_test.py:81:5:81:7 | SSA variable url | +| full_partial_test.py:71:18:71:24 | ControlFlowNode for request | full_partial_test.py:71:5:71:14 | SSA variable user_input | | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | full_partial_test.py:71:5:71:14 | SSA variable user_input | | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | full_partial_test.py:72:5:72:13 | SSA variable query_val | | full_partial_test.py:72:5:72:13 | SSA variable query_val | full_partial_test.py:81:5:81:7 | SSA variable url | | full_partial_test.py:72:17:72:23 | ControlFlowNode for request | full_partial_test.py:72:5:72:13 | SSA variable query_val | | full_partial_test.py:75:5:75:7 | SSA variable url | full_partial_test.py:76:18:76:20 | ControlFlowNode for url | +| full_partial_test.py:75:5:75:7 | SSA variable url | full_partial_test.py:76:18:76:20 | ControlFlowNode for url | | full_partial_test.py:78:5:78:7 | SSA variable url | full_partial_test.py:79:18:79:20 | ControlFlowNode for url | +| full_partial_test.py:78:5:78:7 | SSA variable url | full_partial_test.py:79:18:79:20 | ControlFlowNode for url | +| full_partial_test.py:81:5:81:7 | SSA variable url | full_partial_test.py:82:18:82:20 | ControlFlowNode for url | | full_partial_test.py:81:5:81:7 | SSA variable url | full_partial_test.py:82:18:82:20 | ControlFlowNode for url | | full_partial_test.py:86:5:86:14 | SSA variable user_input | full_partial_test.py:88:5:88:7 | SSA variable url | | full_partial_test.py:86:18:86:24 | ControlFlowNode for request | full_partial_test.py:86:5:86:14 | SSA variable user_input | @@ -78,18 +114,30 @@ edges | full_partial_test.py:119:18:119:24 | ControlFlowNode for request | full_partial_test.py:119:5:119:14 | SSA variable user_input | | full_partial_test.py:121:5:121:7 | SSA variable url | full_partial_test.py:122:18:122:20 | ControlFlowNode for url | | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:1:26:1:32 | GSSA Variable request | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:1:26:1:32 | GSSA Variable request | | test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:9:19:9:25 | ControlFlowNode for request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:9:19:9:25 | ControlFlowNode for request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:10:19:10:25 | ControlFlowNode for request | | test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:10:19:10:25 | ControlFlowNode for request | | test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:11:18:11:24 | ControlFlowNode for request | | test_http_client.py:9:5:9:15 | SSA variable unsafe_host | test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | +| test_http_client.py:9:5:9:15 | SSA variable unsafe_host | test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | +| test_http_client.py:9:5:9:15 | SSA variable unsafe_host | test_http_client.py:18:27:18:37 | ControlFlowNode for unsafe_host | | test_http_client.py:9:5:9:15 | SSA variable unsafe_host | test_http_client.py:18:27:18:37 | ControlFlowNode for unsafe_host | | test_http_client.py:9:5:9:15 | SSA variable unsafe_host | test_http_client.py:25:27:25:37 | ControlFlowNode for unsafe_host | +| test_http_client.py:9:5:9:15 | SSA variable unsafe_host | test_http_client.py:25:27:25:37 | ControlFlowNode for unsafe_host | | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:9:5:9:15 | SSA variable unsafe_host | +| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:9:5:9:15 | SSA variable unsafe_host | +| test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:10:5:10:15 | SSA variable unsafe_path | | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:10:5:10:15 | SSA variable unsafe_path | | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:11:5:11:14 | SSA variable user_input | | test_http_client.py:10:5:10:15 | SSA variable unsafe_path | test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | +| test_http_client.py:10:5:10:15 | SSA variable unsafe_path | test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | +| test_http_client.py:10:5:10:15 | SSA variable unsafe_path | test_http_client.py:19:25:19:35 | ControlFlowNode for unsafe_path | | test_http_client.py:10:5:10:15 | SSA variable unsafe_path | test_http_client.py:19:25:19:35 | ControlFlowNode for unsafe_path | | test_http_client.py:10:5:10:15 | SSA variable unsafe_path | test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_path | +| test_http_client.py:10:5:10:15 | SSA variable unsafe_path | test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_path | +| test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:10:5:10:15 | SSA variable unsafe_path | | test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:10:5:10:15 | SSA variable unsafe_path | | test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:11:5:11:14 | SSA variable user_input | | test_http_client.py:11:5:11:14 | SSA variable user_input | test_http_client.py:31:5:31:8 | SSA variable path | @@ -98,56 +146,97 @@ edges | test_http_client.py:31:5:31:8 | SSA variable path | test_http_client.py:33:25:33:28 | ControlFlowNode for path | | test_http_client.py:35:5:35:8 | SSA variable path | test_http_client.py:37:25:37:28 | ControlFlowNode for path | | test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | test_requests.py:1:19:1:25 | GSSA Variable request | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | test_requests.py:1:19:1:25 | GSSA Variable request | +| test_requests.py:1:19:1:25 | GSSA Variable request | test_requests.py:6:18:6:24 | ControlFlowNode for request | | test_requests.py:1:19:1:25 | GSSA Variable request | test_requests.py:6:18:6:24 | ControlFlowNode for request | | test_requests.py:6:5:6:14 | SSA variable user_input | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | +| test_requests.py:6:5:6:14 | SSA variable user_input | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | +| test_requests.py:6:18:6:24 | ControlFlowNode for request | test_requests.py:6:5:6:14 | SSA variable user_input | | test_requests.py:6:18:6:24 | ControlFlowNode for request | test_requests.py:6:5:6:14 | SSA variable user_input | nodes | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | full_partial_test.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | full_partial_test.py:7:5:7:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| full_partial_test.py:7:5:7:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| full_partial_test.py:7:18:7:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:8:5:8:13 | SSA variable query_val | semmle.label | SSA variable query_val | | full_partial_test.py:8:17:8:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | +| full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | +| full_partial_test.py:12:5:12:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:12:5:12:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:13:18:13:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:13:18:13:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:18:5:18:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:18:5:18:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:19:18:19:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:19:18:19:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:22:5:22:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:22:5:22:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:23:18:23:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:23:18:23:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:37:5:37:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| full_partial_test.py:37:5:37:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| full_partial_test.py:37:18:37:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:38:5:38:13 | SSA variable query_val | semmle.label | SSA variable query_val | | full_partial_test.py:38:17:38:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:41:5:41:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:41:5:41:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:42:18:42:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:42:18:42:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:44:5:44:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:44:5:44:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:45:18:45:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:45:18:45:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:47:5:47:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:47:5:47:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:48:18:48:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:48:18:48:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:50:5:50:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:50:5:50:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:51:18:51:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:51:18:51:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:53:5:53:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:53:5:53:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:54:18:54:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:54:18:54:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:57:5:57:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| full_partial_test.py:57:5:57:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| full_partial_test.py:57:18:57:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:58:5:58:13 | SSA variable query_val | semmle.label | SSA variable query_val | | full_partial_test.py:58:17:58:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:61:5:61:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:61:5:61:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:62:18:62:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:62:18:62:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:64:5:64:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:64:5:64:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:65:18:65:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:65:18:65:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:67:5:67:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:68:18:68:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:71:5:71:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| full_partial_test.py:71:5:71:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| full_partial_test.py:71:18:71:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:72:5:72:13 | SSA variable query_val | semmle.label | SSA variable query_val | | full_partial_test.py:72:17:72:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:75:5:75:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:75:5:75:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:76:18:76:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:76:18:76:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:78:5:78:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:78:5:78:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:79:18:79:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:79:18:79:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:81:5:81:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:81:5:81:7 | SSA variable url | semmle.label | SSA variable url | +| full_partial_test.py:82:18:82:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:82:18:82:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:86:5:86:14 | SSA variable user_input | semmle.label | SSA variable user_input | | full_partial_test.py:86:18:86:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | @@ -174,27 +263,44 @@ nodes | full_partial_test.py:121:5:121:7 | SSA variable url | semmle.label | SSA variable url | | full_partial_test.py:122:18:122:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_http_client.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | test_http_client.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | test_http_client.py:9:5:9:15 | SSA variable unsafe_host | semmle.label | SSA variable unsafe_host | +| test_http_client.py:9:5:9:15 | SSA variable unsafe_host | semmle.label | SSA variable unsafe_host | +| test_http_client.py:9:19:9:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test_http_client.py:9:19:9:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test_http_client.py:10:5:10:15 | SSA variable unsafe_path | semmle.label | SSA variable unsafe_path | +| test_http_client.py:10:5:10:15 | SSA variable unsafe_path | semmle.label | SSA variable unsafe_path | +| test_http_client.py:10:19:10:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test_http_client.py:10:19:10:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test_http_client.py:11:5:11:14 | SSA variable user_input | semmle.label | SSA variable user_input | | test_http_client.py:11:18:11:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host | +| test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host | +| test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path | | test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path | | test_http_client.py:18:27:18:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host | +| test_http_client.py:18:27:18:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host | +| test_http_client.py:19:25:19:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path | | test_http_client.py:19:25:19:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path | | test_http_client.py:25:27:25:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host | +| test_http_client.py:25:27:25:37 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host | +| test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path | | test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path | | test_http_client.py:31:5:31:8 | SSA variable path | semmle.label | SSA variable path | | test_http_client.py:33:25:33:28 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | | test_http_client.py:35:5:35:8 | SSA variable path | semmle.label | SSA variable path | | test_http_client.py:37:25:37:28 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | | test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_requests.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | test_requests.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | test_requests.py:6:5:6:14 | SSA variable user_input | semmle.label | SSA variable user_input | +| test_requests.py:6:5:6:14 | SSA variable user_input | semmle.label | SSA variable user_input | | test_requests.py:6:18:6:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test_requests.py:6:18:6:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test_requests.py:8:18:8:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | subpaths #select