Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e970329

Browse files
committed
Python: Move PathInjection to new dataflow API
1 parent 245c240 commit e970329

3 files changed

Lines changed: 61 additions & 6 deletions

File tree

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+
private 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/src/Security/CWE-022/PathInjection.ql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818

1919
import python
2020
import semmle.python.security.dataflow.PathInjectionQuery
21-
import DataFlow::PathGraph
21+
import PathInjectionFlow::PathGraph
2222

23-
from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
24-
where config.hasFlowPath(source, sink)
23+
from PathInjectionFlow::PathNode source, PathInjectionFlow::PathNode sink
24+
where PathInjectionFlow::flowPath(source, sink)
2525
select sink.getNode(), source, sink, "This path depends on a $@.", source.getNode(),
2626
"user-provided value"

python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ edges
5353
| path_injection.py:84:16:84:22 | ControlFlowNode for request | path_injection.py:84:16:84:27 | ControlFlowNode for Attribute |
5454
| path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | path_injection.py:84:16:84:47 | ControlFlowNode for Attribute() |
5555
| path_injection.py:84:16:84:47 | ControlFlowNode for Attribute() | path_injection.py:84:5:84:12 | SSA variable filename |
56-
| path_injection.py:85:5:85:24 | SSA variable possibly_unsafe_path | path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path |
56+
| path_injection.py:85:5:85:24 | SSA variable possibly_unsafe_path | path_injection.py:86:24:86:43 | ControlFlowNode for possibly_unsafe_path |
57+
| path_injection.py:86:24:86:43 | ControlFlowNode for possibly_unsafe_path | path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path |
5758
| path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | path_injection.py:93:5:93:8 | SSA variable path |
5859
| path_injection.py:93:5:93:8 | SSA variable path | path_injection.py:94:14:94:17 | ControlFlowNode for path |
5960
| path_injection.py:98:20:98:22 | ControlFlowNode for foo | path_injection.py:101:5:101:8 | SSA variable path |
@@ -78,7 +79,8 @@ edges
7879
| path_injection.py:138:16:138:22 | ControlFlowNode for request | path_injection.py:138:16:138:27 | ControlFlowNode for Attribute |
7980
| path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | path_injection.py:138:16:138:47 | ControlFlowNode for Attribute() |
8081
| path_injection.py:138:16:138:47 | ControlFlowNode for Attribute() | path_injection.py:138:5:138:12 | SSA variable filename |
81-
| path_injection.py:139:5:139:8 | SSA variable path | path_injection.py:142:14:142:17 | ControlFlowNode for path |
82+
| path_injection.py:139:5:139:8 | SSA variable path | path_injection.py:140:47:140:50 | ControlFlowNode for path |
83+
| path_injection.py:140:47:140:50 | ControlFlowNode for path | path_injection.py:142:14:142:17 | ControlFlowNode for path |
8284
| path_injection.py:149:5:149:12 | SSA variable filename | path_injection.py:151:9:151:12 | SSA variable path |
8385
| path_injection.py:149:16:149:22 | ControlFlowNode for request | path_injection.py:149:16:149:27 | ControlFlowNode for Attribute |
8486
| path_injection.py:149:16:149:27 | ControlFlowNode for Attribute | path_injection.py:149:16:149:47 | ControlFlowNode for Attribute() |
@@ -171,6 +173,7 @@ nodes
171173
| path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
172174
| path_injection.py:84:16:84:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
173175
| path_injection.py:85:5:85:24 | SSA variable possibly_unsafe_path | semmle.label | SSA variable possibly_unsafe_path |
176+
| path_injection.py:86:24:86:43 | ControlFlowNode for possibly_unsafe_path | semmle.label | ControlFlowNode for possibly_unsafe_path |
174177
| path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | semmle.label | ControlFlowNode for possibly_unsafe_path |
175178
| path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | semmle.label | ControlFlowNode for foo_id |
176179
| path_injection.py:93:5:93:8 | SSA variable path | semmle.label | SSA variable path |
@@ -202,6 +205,7 @@ nodes
202205
| path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
203206
| path_injection.py:138:16:138:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
204207
| path_injection.py:139:5:139:8 | SSA variable path | semmle.label | SSA variable path |
208+
| path_injection.py:140:47:140:50 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
205209
| path_injection.py:142:14:142:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
206210
| path_injection.py:149:5:149:12 | SSA variable filename | semmle.label | SSA variable filename |
207211
| path_injection.py:149:16:149:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |

0 commit comments

Comments
 (0)