Skip to content

Commit e8190d9

Browse files
committed
Python: Track taint through 'yield' expressions.
1 parent 97c98f2 commit e8190d9

File tree

8 files changed

+60
-0
lines changed

8 files changed

+60
-0
lines changed

python/ql/src/semmle/python/security/TaintTracking.qll

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,8 @@ library module TaintFlowImplementation {
875875
or
876876
iteration_step(fromnode, totaint, tocontext, tonode)
877877
or
878+
yield_step(fromnode, totaint, tocontext, tonode)
879+
or
878880
exists(DataFlowNode fromnodenode |
879881
fromnodenode = fromnode.getNode() and
880882
(
@@ -1065,6 +1067,26 @@ library module TaintFlowImplementation {
10651067
)
10661068
}
10671069

1070+
predicate yield_step(TaintedNode fromnode, TrackedValue totaint, CallContext tocontext, CallNode call) {
1071+
exists(PyFunctionObject func |
1072+
func.getFunction().isGenerator() and
1073+
func.getACall() = call and
1074+
(
1075+
fromnode.getContext() = tocontext.getCallee(call)
1076+
or
1077+
fromnode.getContext() = tocontext and tocontext = TTop()
1078+
) and
1079+
exists(Yield yield |
1080+
yield.getScope() = func.getFunction() and
1081+
yield.getValue() = fromnode.getNode().getNode()
1082+
) and
1083+
exists(SequenceKind seq |
1084+
seq.getItem() = fromnode.getTaintKind() and
1085+
totaint = fromnode.getTrackedValue().toKind(seq)
1086+
)
1087+
)
1088+
}
1089+
10681090
predicate call_taint_step(TaintedNode fromnode, TrackedValue totaint, CallContext tocontext, CallNode call) {
10691091
exists(string name |
10701092
call.getFunction().(AttrNode).getObject(name) = fromnode.getNode() and

python/ql/test/library-tests/taint/general/TestDefn.expected

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,9 @@
183183
| test.py:202 | ITERABLE_SOURCE | test.py:202 | Taint iterable.simple | ITERABLE_SOURCE |
184184
| test.py:203 | IterationDefinition | test.py:203 | Taint simple.test | i |
185185
| test.py:203 | phi(i_0, i_2) | test.py:203 | Taint simple.test | i |
186+
| test.py:208 | List | test.py:208 | Taint [simple.test] | List |
187+
| test.py:209 | IterationDefinition | test.py:209 | Taint simple.test | i |
188+
| test.py:209 | phi(i_0, i_2) | test.py:209 | Taint simple.test | i |
189+
| test.py:213 | IterationDefinition | test.py:213 | Taint simple.test | x |
190+
| test.py:213 | phi(x_2, x_3) | test.py:213 | Taint simple.test | x |
191+
| test.py:214 | ArgumentRefinement(x_1) | test.py:213 | Taint simple.test | x |

python/ql/test/library-tests/taint/general/TestNode.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@
6767
| Taint [simple.test] | test.py:172 | x | |
6868
| Taint [simple.test] | test.py:174 | l | |
6969
| Taint [simple.test] | test.py:174 | list() | |
70+
| Taint [simple.test] | test.py:208 | List | |
71+
| Taint [simple.test] | test.py:209 | seq | |
72+
| Taint [simple.test] | test.py:213 | flow_in_generator() | |
7073
| Taint basic.custom | test.py:72 | arg | test.py:121 |
7174
| Taint basic.custom | test.py:73 | arg | test.py:121 |
7275
| Taint basic.custom | test.py:120 | CUSTOM_SOURCE | |
@@ -231,6 +234,11 @@
231234
| Taint simple.test | test.py:203 | i | |
232235
| Taint simple.test | test.py:204 | i | |
233236
| Taint simple.test | test.py:205 | i | |
237+
| Taint simple.test | test.py:208 | SOURCE | |
238+
| Taint simple.test | test.py:209 | i | |
239+
| Taint simple.test | test.py:210 | i | |
240+
| Taint simple.test | test.py:213 | x | |
241+
| Taint simple.test | test.py:214 | x | |
234242
| Taint {simple.test} | test.py:169 | Dict | |
235243
| Taint {simple.test} | test.py:171 | d | |
236244
| Taint {simple.test} | test.py:173 | y | |

python/ql/test/library-tests/taint/general/TestSink.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,4 @@
3636
| simple.test | test.py:178 | 186 | t | simple.test |
3737
| simple.test | test.py:195 | 197 | t | simple.test |
3838
| simple.test | test.py:195 | 199 | t | simple.test |
39+
| simple.test | test.py:208 | 214 | x | simple.test |

python/ql/test/library-tests/taint/general/TestSource.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,4 @@
4444
| test.py:189 | FALSEY | falsey |
4545
| test.py:195 | SOURCE | simple.test |
4646
| test.py:202 | ITERABLE_SOURCE | iterable.simple |
47+
| test.py:208 | SOURCE | simple.test |

python/ql/test/library-tests/taint/general/TestStep.expected

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@
5959
| Taint [simple.test] | test.py:170 | l | | --> | Taint [simple.test] | test.py:172 | x | |
6060
| Taint [simple.test] | test.py:172 | x | | --> | Taint simple.test | test.py:172 | Subscript | |
6161
| Taint [simple.test] | test.py:174 | l | | --> | Taint [simple.test] | test.py:174 | list() | |
62+
| Taint [simple.test] | test.py:208 | List | | --> | Taint [simple.test] | test.py:209 | seq | |
63+
| Taint [simple.test] | test.py:209 | seq | | --> | Taint simple.test | test.py:209 | i | |
64+
| Taint [simple.test] | test.py:213 | flow_in_generator() | | --> | Taint simple.test | test.py:213 | x | |
6265
| Taint basic.custom | test.py:72 | arg | test.py:121 | --> | Taint basic.custom | test.py:73 | arg | test.py:121 |
6366
| Taint basic.custom | test.py:73 | arg | test.py:121 | --> | Taint basic.custom | test.py:121 | hub() | |
6467
| Taint basic.custom | test.py:120 | CUSTOM_SOURCE | | --> | Taint basic.custom | test.py:121 | t | |
@@ -185,6 +188,10 @@
185188
| Taint simple.test | test.py:195 | SOURCE | | --> | Taint simple.test | test.py:199 | t | |
186189
| Taint simple.test | test.py:203 | i | | --> | Taint simple.test | test.py:204 | i | |
187190
| Taint simple.test | test.py:203 | i | | --> | Taint simple.test | test.py:205 | i | |
191+
| Taint simple.test | test.py:208 | SOURCE | | --> | Taint [simple.test] | test.py:208 | List | |
192+
| Taint simple.test | test.py:209 | i | | --> | Taint simple.test | test.py:210 | i | |
193+
| Taint simple.test | test.py:210 | i | | --> | Taint [simple.test] | test.py:213 | flow_in_generator() | |
194+
| Taint simple.test | test.py:213 | x | | --> | Taint simple.test | test.py:214 | x | |
188195
| Taint {simple.test} | test.py:169 | Dict | | --> | Taint {simple.test} | test.py:171 | d | |
189196
| Taint {simple.test} | test.py:169 | Dict | | --> | Taint {simple.test} | test.py:175 | d | |
190197
| Taint {simple.test} | test.py:171 | d | | --> | Taint {simple.test} | test.py:173 | y | |

python/ql/test/library-tests/taint/general/TestVar.expected

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,9 @@
185185
| test.py:202 | t_0 | test.py:202 | Taint iterable.simple | ITERABLE_SOURCE |
186186
| test.py:203 | i_1 | test.py:203 | Taint simple.test | i |
187187
| test.py:203 | i_2 | test.py:203 | Taint simple.test | i |
188+
| test.py:208 | seq_0 | test.py:208 | Taint [simple.test] | List |
189+
| test.py:209 | i_1 | test.py:209 | Taint simple.test | i |
190+
| test.py:209 | i_2 | test.py:209 | Taint simple.test | i |
191+
| test.py:213 | x_0 | test.py:213 | Taint simple.test | x |
192+
| test.py:213 | x_1 | test.py:213 | Taint simple.test | x |
193+
| test.py:214 | x_2 | test.py:213 | Taint simple.test | x |

python/ql/test/library-tests/taint/general/test.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,12 @@ def flow_in_iteration():
204204
i
205205
return i
206206

207+
def flow_in_generator():
208+
seq = [SOURCE]
209+
for i in seq:
210+
yield i
211+
212+
def flow_from_generator():
213+
for x in flow_in_generator():
214+
SINK(x)
215+

0 commit comments

Comments
 (0)