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

Skip to content

Commit 3872c7a

Browse files
committed
Python taint-tracking. Rework handling of sequences and dicts of taint for performance.
1 parent a36453b commit 3872c7a

2 files changed

Lines changed: 59 additions & 27 deletions

File tree

python/ql/src/semmle/python/dataflow/Implementation.qll

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,19 @@ class TaintTrackingImplementation extends string {
361361
|
362362
kind = srckind.getTaintForFlowStep(srcnode.asCfgNode(), node.asCfgNode(), edgeLabel)
363363
or
364-
kind.isResultOfStep(srckind, srcnode.asCfgNode(), node.asCfgNode(), edgeLabel)
364+
kind = srckind.(CollectionKind).getMember() and
365+
srckind.(CollectionKind).flowToMember(srcnode, node) and
366+
edgeLabel = "to member"
367+
or
368+
srckind = kind.(CollectionKind).getMember() and
369+
kind.(CollectionKind).flowFromMember(srcnode, node) and
370+
edgeLabel = "from member"
371+
or
372+
kind = srckind and srckind.flowStep(srcnode, node, edgeLabel)
373+
or
374+
kind = srckind and srckind instanceof DictKind and DictKind::flowStep(srcnode.asCfgNode(), node.asCfgNode(), edgeLabel)
375+
or
376+
kind = srckind and srckind instanceof SequenceKind and SequenceKind::flowStep(srcnode.asCfgNode(), node.asCfgNode(), edgeLabel)
365377
)
366378
}
367379

@@ -755,11 +767,13 @@ private class EssaTaintTracking extends string {
755767
or
756768
result = testEvaluates(not_operand(test), use, kind).booleanNot()
757769
or
770+
kind.taints(use) and
758771
exists(ControlFlowNode const |
759772
Filters::equality_test(test, use, result.booleanNot(), const) and
760773
const.getNode() instanceof ImmutableLiteral
761774
)
762775
or
776+
kind.taints(use) and
763777
exists(ControlFlowNode c, ClassValue cls |
764778
Filters::isinstance(test, c, use) and
765779
c.pointsTo(cls)

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

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,6 @@ abstract class TaintKind extends string {
126126
result = this.getTaintForFlowStep(fromnode, tonode) and edgeLabel = "custom taint flow step for " + this
127127
}
128128

129-
predicate isResultOfStep(TaintKind fromkind, ControlFlowNode fromnode, ControlFlowNode tonode) { none() }
130-
131-
predicate isResultOfStep(TaintKind fromkind, ControlFlowNode fromnode, ControlFlowNode tonode, string edgeLabel) {
132-
this.isResultOfStep(fromkind, fromnode, tonode) and edgeLabel = "custom taint reverse flow step for " + this
133-
}
134-
135129
/** DEPRECATED -- Use `TaintFlow.additionalFlowStepVar(EssaVariable fromvar, EssaVariable tovar, TaintKind kind)` instead.
136130
*
137131
* Holds if this kind of taint passes from variable `fromvar` to variable `tovar`
@@ -179,6 +173,10 @@ abstract class TaintKind extends string {
179173
*/
180174
TaintKind getTaintForIteration() { none() }
181175

176+
predicate flowStep(DataFlow::Node fromnode, DataFlow::Node tonode, string edgeLabel) {
177+
this.additionalFlowStepVar(fromnode.asVariable(), tonode.asVariable()) and
178+
edgeLabel = "custom taint variable step"
179+
}
182180
}
183181

184182
/**
@@ -202,6 +200,11 @@ abstract class CollectionKind extends TaintKind {
202200
not this.charAt(2) = "[" and not this.charAt(2) = "{"
203201
}
204202

203+
abstract TaintKind getMember();
204+
205+
abstract predicate flowFromMember(DataFlow::Node fromnode, DataFlow::Node tonode);
206+
207+
abstract predicate flowToMember(DataFlow::Node fromnode, DataFlow::Node tonode);
205208
}
206209

207210
/** A taint kind representing a flat collections of kinds.
@@ -227,8 +230,6 @@ class SequenceKind extends CollectionKind {
227230
result = this.getItem() and
228231
result.getType() = ObjectInternal::builtin("str")
229232
)
230-
or
231-
result = this.getItem() and SequenceKind::itemFlowStep(fromnode, tonode)
232233
}
233234

234235
override TaintKind getTaintOfMethodResult(string name) {
@@ -243,25 +244,32 @@ class SequenceKind extends CollectionKind {
243244
result = itemKind
244245
}
245246

246-
override predicate isResultOfStep(TaintKind fromkind, ControlFlowNode fromnode, ControlFlowNode tonode) {
247-
SequenceKind::flowStep(fromnode, tonode) and this = fromkind
248-
or
249-
sequence_construct(fromnode, tonode) and this.getItem() = fromkind
247+
override TaintKind getMember() {
248+
result = itemKind
249+
}
250+
251+
override predicate flowFromMember(DataFlow::Node fromnode, DataFlow::Node tonode) {
252+
sequence_construct(fromnode.asCfgNode(), tonode.asCfgNode())
253+
}
254+
255+
override predicate flowToMember(DataFlow::Node fromnode, DataFlow::Node tonode) {
256+
SequenceKind::itemFlowStep(fromnode.asCfgNode(), tonode.asCfgNode())
250257
}
251258

252259
}
253260

254261

255262
module SequenceKind {
256263

257-
predicate flowStep(ControlFlowNode fromnode, ControlFlowNode tonode) {
258-
tonode.(BinaryExprNode).getAnOperand() = fromnode
264+
predicate flowStep(ControlFlowNode fromnode, ControlFlowNode tonode, string edgeLabel) {
265+
tonode.(BinaryExprNode).getAnOperand() = fromnode and edgeLabel = "binary operation"
259266
or
260-
Implementation::copyCall(fromnode, tonode)
267+
Implementation::copyCall(fromnode, tonode) and
268+
edgeLabel = "dict copy"
261269
or
262-
sequence_call(fromnode, tonode)
270+
sequence_call(fromnode, tonode) and edgeLabel = "sequence construction"
263271
or
264-
subscript_slice(fromnode, tonode)
272+
subscript_slice(fromnode, tonode) and edgeLabel = "slicing"
265273
}
266274

267275
predicate itemFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) {
@@ -270,6 +278,17 @@ module SequenceKind {
270278

271279
}
272280

281+
module DictKind {
282+
predicate flowStep(ControlFlowNode fromnode, ControlFlowNode tonode, string edgeLabel) {
283+
Implementation::copyCall(fromnode, tonode) and
284+
edgeLabel = "dict copy"
285+
or
286+
tonode.(CallNode).getFunction().pointsTo(ObjectInternal::builtin("dict")) and
287+
tonode.(CallNode).getArg(0) = fromnode and
288+
edgeLabel = "dict() call"
289+
}
290+
}
291+
273292

274293
/* Helper for sequence flow steps */
275294
pragma [noinline]
@@ -314,17 +333,16 @@ class DictKind extends CollectionKind {
314333
result = "dict of " + valueKind
315334
}
316335

317-
override predicate isResultOfStep(TaintKind fromkind, ControlFlowNode fromnode, ControlFlowNode tonode) {
318-
Implementation::copyCall(fromnode, tonode) and this = fromkind
319-
or
320-
tonode.(CallNode).getFunction().pointsTo(ObjectInternal::builtin("dict")) and
321-
tonode.(CallNode).getArg(0) = fromnode and this = fromkind
322-
or
323-
dict_construct(fromnode, tonode) and this.getValue() = fromkind
336+
override TaintKind getMember() {
337+
result = valueKind
324338
}
325339

326-
override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) {
327-
subscript_index(fromnode, tonode) and result = this.getValue()
340+
override predicate flowFromMember(DataFlow::Node fromnode, DataFlow::Node tonode) {
341+
dict_construct(fromnode.asCfgNode(), tonode.asCfgNode())
342+
}
343+
344+
override predicate flowToMember(DataFlow::Node fromnode, DataFlow::Node tonode) {
345+
subscript_index(fromnode.asCfgNode(), tonode.asCfgNode())
328346
}
329347

330348
}

0 commit comments

Comments
 (0)