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

Skip to content

Commit e8bd9e7

Browse files
committed
Python: Add new API for taint-tracking configuration. As yet, unsupported.
1 parent d2bee79 commit e8bd9e7

2 files changed

Lines changed: 117 additions & 41 deletions

File tree

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import python
2+
import semmle.python.security.TaintTracking
3+
4+
module TaintTracking {
5+
6+
class Source = TaintSource;
7+
8+
class Sink = TaintSink;
9+
10+
class PathSource = TaintedPathSource;
11+
12+
class PathSink = TaintedPathSink;
13+
14+
class Extension = DataFlowExtension::DataFlowNode;
15+
16+
abstract class Configuration extends string {
17+
18+
/* Required to prevent compiler warning */
19+
bindingset[this]
20+
Configuration() { this = this }
21+
22+
/* Old implementation API */
23+
24+
predicate isSource(Source source) { none() }
25+
26+
predicate isSink(Sink sink) { none() }
27+
28+
predicate isSanitizer(Sanitizer sanitizer) { none() }
29+
30+
predicate isExtension(Extension extension) { none() }
31+
32+
/* New implementation API */
33+
34+
/**
35+
* Holds if `source` is a source of taint of `kind` that is relevant
36+
* for this configuration.
37+
*/
38+
predicate isSource(DataFlow::Node source, TaintKind kind) { none() }
39+
40+
/**
41+
* Holds if `sink` is a sink of taint of `kind` that is relevant
42+
* for this configuration.
43+
*/
44+
predicate isSink(DataFlow::Node sink, TaintKind kind) { none() }
45+
46+
/**
47+
* Holds if `src -> dest` should be considered as a flow edge
48+
* in addition to standard data flow edges.
49+
*/
50+
predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node dest) { none() }
51+
52+
/**
53+
* Holds if `src -> dest` is a flow edge converting taint from `srckind` to `destkind`.
54+
*/
55+
predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg, TaintKind srckind, TaintKind destkind) {
56+
none()
57+
}
58+
59+
predicate isBarrier(DataFlow::Node node) { none() }
60+
61+
predicate isBarrier(DataFlow::Node node, TaintKind kind) { none() }
62+
63+
/**
64+
* Holds if flow from `src` to `dest` is prohibited.
65+
*/
66+
predicate isBarrierEdge(DataFlow::Node src, DataFlow::Node trg) { none() }
67+
68+
/**
69+
* Holds if flow from `src` to `dest` is prohibited when the incoming taint is `srckind` and the outgoing taint is `destkind`.
70+
* Note that `srckind` and `destkind` can be the same.
71+
*/
72+
predicate isBarrierEdge(DataFlow::Node src, DataFlow::Node dest, TaintKind srckind, TaintKind destkind) { none() }
73+
74+
/* Common query API */
75+
76+
predicate hasFlowPath(PathSource source, PathSink sink) {
77+
this.isSource(source.getNode()) and
78+
this.isSink(sink.getNode()) and
79+
source.flowsTo(sink)
80+
}
81+
82+
/* Old query API */
83+
84+
deprecated predicate hasFlow(Source source, Sink sink) {
85+
exists(PathSource psource, PathSink psink |
86+
this.hasFlowPath(psource, psink) and
87+
source = psource.getCfgNode() and
88+
sink = psink.getCfgNode()
89+
)
90+
}
91+
92+
/* New query API */
93+
94+
predicate hasSimpleFlow(DataFlow::Node source, DataFlow::Node sink) {
95+
/* TO DO */
96+
exists(PathSource psource, PathSink psink |
97+
this.hasFlowPath(psource, psink) and
98+
source = psource.getNode() and
99+
sink = psink.getNode()
100+
)
101+
}
102+
103+
}
104+
105+
}
106+

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

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
import python
9090
private import semmle.python.pointsto.Filters as Filters
9191
private import semmle.python.objects.ObjectInternal
92+
import semmle.python.dataflow.Configuration
9293

9394
/** A 'kind' of taint. This may be almost anything,
9495
* but it is typically something like a "user-defined string".
@@ -167,6 +168,11 @@ abstract class TaintKind extends string {
167168

168169
}
169170

171+
/**
172+
* Alias of `TaintKind`, so the two types can be used interchangeably.
173+
*/
174+
class FlowLabel = TaintKind;
175+
170176
/** Taint kinds representing collections of other taint kind.
171177
* We use `{kind}` to represent a mapping of string to `kind` and
172178
* `[kind]` to represent a flat collection of `kind`.
@@ -670,6 +676,11 @@ class TaintedNode extends TTaintedNode {
670676
result = this.getNode().getNode()
671677
}
672678

679+
/** Gets the CFG node for this node. */
680+
ControlFlowNode getCfgNode() {
681+
this = TTaintedNode_(_, _, result)
682+
}
683+
673684
/** Gets the data-flow context for this node. */
674685
CallContext getContext() {
675686
this = TTaintedNode_(_, result, _)
@@ -1644,47 +1655,6 @@ private class DataFlowType extends TaintKind {
16441655

16451656
}
16461657

1647-
module TaintTracking {
1648-
1649-
class Source = TaintSource;
1650-
1651-
class Sink = TaintSink;
1652-
1653-
class PathSource = TaintedPathSource;
1654-
1655-
class PathSink = TaintedPathSink;
1656-
1657-
class Extension = DataFlowExtension::DataFlowNode;
1658-
1659-
abstract class Configuration extends string {
1660-
1661-
bindingset[this]
1662-
Configuration() { this = this }
1663-
1664-
abstract predicate isSource(Source source);
1665-
1666-
abstract predicate isSink(Sink sink);
1667-
1668-
predicate isSanitizer(Sanitizer sanitizer) { none() }
1669-
1670-
predicate isExtension(Extension extension) { none() }
1671-
1672-
predicate hasFlowPath(PathSource source, PathSink sink) {
1673-
this.isSource(source.getNode()) and
1674-
this.isSink(sink.getNode()) and
1675-
source.flowsTo(sink)
1676-
}
1677-
1678-
predicate hasFlow(Source source, Sink sink) {
1679-
this.isSource(source) and
1680-
this.isSink(sink) and
1681-
source.flowsToSink(sink)
1682-
}
1683-
1684-
}
1685-
1686-
}
1687-
16881658

16891659
pragma [noinline]
16901660
private predicate dict_construct(ControlFlowNode itemnode, ControlFlowNode dictnode) {

0 commit comments

Comments
 (0)