Skip to content

Commit 49f5d38

Browse files
authored
Merge pull request github#14068 from RasmusWL/dataflow-config-refactor
Python: Use new dataflow API
2 parents 4a1163b + ce63358 commit 49f5d38

File tree

108 files changed

+1032
-728
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

108 files changed

+1032
-728
lines changed

python/ql/lib/semmle/python/security/dataflow/CleartextLoggingQuery.qll

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ private import semmle.python.dataflow.new.SensitiveDataSources
1616
import CleartextLoggingCustomizations::CleartextLogging
1717

1818
/**
19+
* DEPRECATED: Use `CleartextLoggingFlow` module instead.
20+
*
1921
* A taint-tracking configuration for detecting "Clear-text logging of sensitive information".
2022
*/
21-
class Configuration extends TaintTracking::Configuration {
23+
deprecated class Configuration extends TaintTracking::Configuration {
2224
Configuration() { this = "CleartextLogging" }
2325

2426
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -31,3 +33,14 @@ class Configuration extends TaintTracking::Configuration {
3133
node instanceof Sanitizer
3234
}
3335
}
36+
37+
private module CleartextLoggingConfig implements DataFlow::ConfigSig {
38+
predicate isSource(DataFlow::Node source) { source instanceof Source }
39+
40+
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
41+
42+
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
43+
}
44+
45+
/** Global taint-tracking for detecting "Clear-text logging of sensitive information" vulnerabilities. */
46+
module CleartextLoggingFlow = TaintTracking::Global<CleartextLoggingConfig>;

python/ql/lib/semmle/python/security/dataflow/CleartextStorageQuery.qll

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ private import semmle.python.dataflow.new.SensitiveDataSources
1616
import CleartextStorageCustomizations::CleartextStorage
1717

1818
/**
19+
* DEPRECATED: Use `CleartextStorageFlow` module instead.
20+
*
1921
* A taint-tracking configuration for detecting "Clear-text storage of sensitive information".
2022
*/
21-
class Configuration extends TaintTracking::Configuration {
23+
deprecated class Configuration extends TaintTracking::Configuration {
2224
Configuration() { this = "CleartextStorage" }
2325

2426
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -31,3 +33,14 @@ class Configuration extends TaintTracking::Configuration {
3133
node instanceof Sanitizer
3234
}
3335
}
36+
37+
private module CleartextStorageConfig implements DataFlow::ConfigSig {
38+
predicate isSource(DataFlow::Node source) { source instanceof Source }
39+
40+
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
41+
42+
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
43+
}
44+
45+
/** Global taint-tracking for detecting "Clear-text storage of sensitive information" vulnerabilities. */
46+
module CleartextStorageFlow = TaintTracking::Global<CleartextStorageConfig>;

python/ql/lib/semmle/python/security/dataflow/CodeInjectionQuery.qll

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ import semmle.python.dataflow.new.TaintTracking
1212
import CodeInjectionCustomizations::CodeInjection
1313

1414
/**
15+
* DEPRECATED: Use `CodeInjectionFlow` module instead.
16+
*
1517
* A taint-tracking configuration for detecting "code injection" vulnerabilities.
1618
*/
17-
class Configuration extends TaintTracking::Configuration {
19+
deprecated class Configuration extends TaintTracking::Configuration {
1820
Configuration() { this = "CodeInjection" }
1921

2022
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -27,3 +29,14 @@ class Configuration extends TaintTracking::Configuration {
2729
guard instanceof SanitizerGuard
2830
}
2931
}
32+
33+
private module CodeInjectionConfig implements DataFlow::ConfigSig {
34+
predicate isSource(DataFlow::Node source) { source instanceof Source }
35+
36+
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
37+
38+
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
39+
}
40+
41+
/** Global taint-tracking for detecting "code injection" vulnerabilities. */
42+
module CodeInjectionFlow = TaintTracking::Global<CodeInjectionConfig>;

python/ql/lib/semmle/python/security/dataflow/CommandInjectionQuery.qll

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ import semmle.python.dataflow.new.TaintTracking
1212
import CommandInjectionCustomizations::CommandInjection
1313

1414
/**
15+
* DEPRECATED: Use `CommandInjectionFlow` module instead.
16+
*
1517
* A taint-tracking configuration for detecting "command injection" vulnerabilities.
1618
*/
17-
class Configuration extends TaintTracking::Configuration {
19+
deprecated class Configuration extends TaintTracking::Configuration {
1820
Configuration() { this = "CommandInjection" }
1921

2022
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -27,3 +29,17 @@ class Configuration extends TaintTracking::Configuration {
2729
guard instanceof SanitizerGuard
2830
}
2931
}
32+
33+
/**
34+
* A taint-tracking configuration for detecting "command injection" vulnerabilities.
35+
*/
36+
module CommandInjectionConfig implements DataFlow::ConfigSig {
37+
predicate isSource(DataFlow::Node source) { source instanceof Source }
38+
39+
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
40+
41+
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
42+
}
43+
44+
/** Global taint-tracking for detecting "command injection" vulnerabilities. */
45+
module CommandInjectionFlow = TaintTracking::Global<CommandInjectionConfig>;

python/ql/lib/semmle/python/security/dataflow/LdapInjectionQuery.qll

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ import semmle.python.dataflow.new.RemoteFlowSources
1414
import LdapInjectionCustomizations::LdapInjection
1515

1616
/**
17+
* DEPRECATED: Use `LdapInjectionDnFlow` module instead.
18+
*
1719
* A taint-tracking configuration for detecting LDAP injection vulnerabilities
1820
* via the distinguished name (DN) parameter of an LDAP search.
1921
*/
20-
class DnConfiguration extends TaintTracking::Configuration {
22+
deprecated class DnConfiguration extends TaintTracking::Configuration {
2123
DnConfiguration() { this = "LdapDnInjection" }
2224

2325
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -31,11 +33,24 @@ class DnConfiguration extends TaintTracking::Configuration {
3133
}
3234
}
3335

36+
private module LdapInjectionDnConfig implements DataFlow::ConfigSig {
37+
predicate isSource(DataFlow::Node source) { source instanceof Source }
38+
39+
predicate isSink(DataFlow::Node sink) { sink instanceof DnSink }
40+
41+
predicate isBarrier(DataFlow::Node node) { node instanceof DnSanitizer }
42+
}
43+
44+
/** Global taint-tracking for detecting "LDAP injection via the distinguished name (DN) parameter" vulnerabilities. */
45+
module LdapInjectionDnFlow = TaintTracking::Global<LdapInjectionDnConfig>;
46+
3447
/**
48+
* DEPRECATED: Use `LdapInjectionFilterFlow` module instead.
49+
*
3550
* A taint-tracking configuration for detecting LDAP injection vulnerabilities
3651
* via the filter parameter of an LDAP search.
3752
*/
38-
class FilterConfiguration extends TaintTracking::Configuration {
53+
deprecated class FilterConfiguration extends TaintTracking::Configuration {
3954
FilterConfiguration() { this = "LdapFilterInjection" }
4055

4156
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -48,3 +63,19 @@ class FilterConfiguration extends TaintTracking::Configuration {
4863
guard instanceof FilterSanitizerGuard
4964
}
5065
}
66+
67+
private module LdapInjectionFilterConfig implements DataFlow::ConfigSig {
68+
predicate isSource(DataFlow::Node source) { source instanceof Source }
69+
70+
predicate isSink(DataFlow::Node sink) { sink instanceof FilterSink }
71+
72+
predicate isBarrier(DataFlow::Node node) { node instanceof FilterSanitizer }
73+
}
74+
75+
/** Global taint-tracking for detecting "LDAP injection via the filter parameter" vulnerabilities. */
76+
module LdapInjectionFilterFlow = TaintTracking::Global<LdapInjectionFilterConfig>;
77+
78+
/** Global taint-tracking for detecting "LDAP injection" vulnerabilities. */
79+
module LdapInjectionFlow =
80+
DataFlow::MergePathGraph<LdapInjectionDnFlow::PathNode, LdapInjectionFilterFlow::PathNode,
81+
LdapInjectionDnFlow::PathGraph, LdapInjectionFilterFlow::PathGraph>;

python/ql/lib/semmle/python/security/dataflow/LogInjectionQuery.qll

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Provides a taint-tracking configuration for tracking untrusted user input used in log entries.
2+
* Provides a taint-tracking configuration for tracking "log injection" vulnerabilities.
33
*
44
* Note, for performance reasons: only import this file if
55
* `LogInjection::Configuration` is needed, otherwise
@@ -12,9 +12,11 @@ import semmle.python.dataflow.new.TaintTracking
1212
import LogInjectionCustomizations::LogInjection
1313

1414
/**
15+
* DEPRECATED: Use `LogInjectionFlow` module instead.
16+
*
1517
* A taint-tracking configuration for tracking untrusted user input used in log entries.
1618
*/
17-
class Configuration extends TaintTracking::Configuration {
19+
deprecated class Configuration extends TaintTracking::Configuration {
1820
Configuration() { this = "LogInjection" }
1921

2022
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -27,3 +29,14 @@ class Configuration extends TaintTracking::Configuration {
2729
guard instanceof SanitizerGuard
2830
}
2931
}
32+
33+
private module LogInjectionConfig implements DataFlow::ConfigSig {
34+
predicate isSource(DataFlow::Node source) { source instanceof Source }
35+
36+
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
37+
38+
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
39+
}
40+
41+
/** Global taint-tracking for detecting "log injection" vulnerabilities. */
42+
module LogInjectionFlow = TaintTracking::Global<LogInjectionConfig>;

python/ql/lib/semmle/python/security/dataflow/PamAuthorizationQuery.qll

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ import semmle.python.dataflow.new.TaintTracking
1212
import PamAuthorizationCustomizations::PamAuthorizationCustomizations
1313

1414
/**
15+
* DEPRECATED: Use `PamAuthorizationFlow` module instead.
16+
*
1517
* A taint-tracking configuration for detecting "PAM Authorization" vulnerabilities.
1618
*/
17-
class Configuration extends TaintTracking::Configuration {
19+
deprecated class Configuration extends TaintTracking::Configuration {
1820
Configuration() { this = "PamAuthorization" }
1921

2022
override predicate isSource(DataFlow::Node node) { node instanceof Source }
@@ -37,3 +39,28 @@ class Configuration extends TaintTracking::Configuration {
3739
exists(VulnPamAuthCall c | c.getArg(0) = node1 | node2 = c)
3840
}
3941
}
42+
43+
private module PamAuthorizationConfig implements DataFlow::ConfigSig {
44+
predicate isSource(DataFlow::Node source) { source instanceof Source }
45+
46+
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
47+
48+
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
49+
// Models flow from a remotely supplied username field to a PAM `handle`.
50+
// `retval = pam_start(service, username, byref(conv), byref(handle))`
51+
exists(API::CallNode pamStart, DataFlow::Node handle, API::CallNode pointer |
52+
pointer = API::moduleImport("ctypes").getMember(["pointer", "byref"]).getACall() and
53+
pamStart = libPam().getMember("pam_start").getACall() and
54+
pointer = pamStart.getArg(3) and
55+
handle = pointer.getArg(0) and
56+
pamStart.getArg(1) = node1 and
57+
handle = node2
58+
)
59+
or
60+
// Flow from handle to the authenticate call in the final step
61+
exists(VulnPamAuthCall c | c.getArg(0) = node1 | node2 = c)
62+
}
63+
}
64+
65+
/** Global taint-tracking for detecting "PAM Authorization" vulnerabilities. */
66+
module PamAuthorizationFlow = TaintTracking::Global<PamAuthorizationConfig>;

python/ql/lib/semmle/python/security/dataflow/PathInjectionQuery.qll

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import semmle.python.dataflow.new.TaintTracking
1313
import PathInjectionCustomizations::PathInjection
1414

1515
/**
16+
* DEPRECATED: Use `PathInjectionFlow` module instead.
17+
*
1618
* A taint-tracking configuration for detecting "path injection" vulnerabilities.
1719
*
1820
* This configuration uses two flow states, `NotNormalized` and `NormalizedUnchecked`,
@@ -25,7 +27,7 @@ import PathInjectionCustomizations::PathInjection
2527
*
2628
* Such checks are ineffective in the `NotNormalized` state.
2729
*/
28-
class Configuration extends TaintTracking::Configuration {
30+
deprecated class Configuration extends TaintTracking::Configuration {
2931
Configuration() { this = "PathInjection" }
3032

3133
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
@@ -74,3 +76,52 @@ class NotNormalized extends DataFlow::FlowState {
7476
class NormalizedUnchecked extends DataFlow::FlowState {
7577
NormalizedUnchecked() { this = "NormalizedUnchecked" }
7678
}
79+
80+
/**
81+
* This configuration uses two flow states, `NotNormalized` and `NormalizedUnchecked`,
82+
* to track the requirement that a file path must be first normalized and then checked
83+
* before it is safe to use.
84+
*
85+
* At sources, paths are assumed not normalized. At normalization points, they change
86+
* state to `NormalizedUnchecked` after which they can be made safe by an appropriate
87+
* check of the prefix.
88+
*
89+
* Such checks are ineffective in the `NotNormalized` state.
90+
*/
91+
module PathInjectionConfig implements DataFlow::StateConfigSig {
92+
class FlowState = DataFlow::FlowState;
93+
94+
predicate isSource(DataFlow::Node source, FlowState state) {
95+
source instanceof Source and state instanceof NotNormalized
96+
}
97+
98+
predicate isSink(DataFlow::Node sink, FlowState state) {
99+
sink instanceof Sink and
100+
(
101+
state instanceof NotNormalized or
102+
state instanceof NormalizedUnchecked
103+
)
104+
}
105+
106+
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
107+
108+
predicate isBarrier(DataFlow::Node node, FlowState state) {
109+
// Block `NotNormalized` paths here, since they change state to `NormalizedUnchecked`
110+
node instanceof Path::PathNormalization and
111+
state instanceof NotNormalized
112+
or
113+
node instanceof Path::SafeAccessCheck and
114+
state instanceof NormalizedUnchecked
115+
}
116+
117+
predicate isAdditionalFlowStep(
118+
DataFlow::Node nodeFrom, FlowState stateFrom, DataFlow::Node nodeTo, FlowState stateTo
119+
) {
120+
nodeFrom = nodeTo.(Path::PathNormalization).getPathArg() and
121+
stateFrom instanceof NotNormalized and
122+
stateTo instanceof NormalizedUnchecked
123+
}
124+
}
125+
126+
/** Global taint-tracking for detecting "path injection" vulnerabilities. */
127+
module PathInjectionFlow = TaintTracking::GlobalWithState<PathInjectionConfig>;

python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSCustomizations.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
private import python
88
private import semmle.python.dataflow.new.DataFlow
9-
private import semmle.python.dataflow.new.DataFlow2
109
private import semmle.python.dataflow.new.TaintTracking
1110
private import semmle.python.Concepts
1211
private import semmle.python.dataflow.new.RemoteFlowSources

python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSQuery.qll

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ import semmle.python.dataflow.new.TaintTracking
1212
import PolynomialReDoSCustomizations::PolynomialReDoS
1313

1414
/**
15+
* DEPRECATED: Use `PolynomialReDoSFlow` module instead.
16+
*
1517
* A taint-tracking configuration for detecting "polynomial regular expression denial of service (ReDoS)" vulnerabilities.
1618
*/
17-
class Configuration extends TaintTracking::Configuration {
19+
deprecated class Configuration extends TaintTracking::Configuration {
1820
Configuration() { this = "PolynomialReDoS" }
1921

2022
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -27,3 +29,14 @@ class Configuration extends TaintTracking::Configuration {
2729
guard instanceof SanitizerGuard
2830
}
2931
}
32+
33+
private module PolynomialReDoSConfig implements DataFlow::ConfigSig {
34+
predicate isSource(DataFlow::Node source) { source instanceof Source }
35+
36+
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
37+
38+
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
39+
}
40+
41+
/** Global taint-tracking for detecting "polynomial regular expression denial of service (ReDoS)" vulnerabilities. */
42+
module PolynomialReDoSFlow = TaintTracking::Global<PolynomialReDoSConfig>;

0 commit comments

Comments
 (0)