Python taint-tracking. Handle early exit and 'not' correctly for 'falsey' taints.

This commit is contained in:
Mark Shannon
2019-03-22 11:42:38 +00:00
parent 36c7a8430a
commit 2edde1fed8
11 changed files with 277 additions and 2 deletions

View File

@@ -334,3 +334,35 @@ class OsCommand extends TaintSink {
}
}
class Falsey extends TaintKind {
Falsey() { this = "falsey" }
override boolean booleanValue() {
result = false
}
}
class FalseySource extends TaintSource {
FalseySource() {
this.(NameNode).getId() = "FALSEY"
}
override predicate isSourceOf(TaintKind kind) {
kind instanceof Falsey
}
override string toString() {
result = "falsey.source"
}
}

View File

@@ -0,0 +1,184 @@
| carrier.py:4 | ParameterDefinition | carrier.py:4 | Taint explicit.carrier | arg |
| carrier.py:4 | ParameterDefinition | carrier.py:4 | Taint simple.test | arg |
| carrier.py:5 | AttributeAssignment 'attr'(self_0) | carrier.py:5 | Attribute 'attr' taint explicit.carrier | self |
| carrier.py:5 | AttributeAssignment 'attr'(self_0) | carrier.py:5 | Attribute 'attr' taint simple.test | self |
| carrier.py:13 | ParameterDefinition | carrier.py:13 | Attribute 'attr' taint simple.test | arg |
| carrier.py:13 | ParameterDefinition | carrier.py:13 | Taint explicit.carrier | arg |
| carrier.py:17 | ImplicitCarrier() | carrier.py:17 | Attribute 'attr' taint simple.test | ImplicitCarrier() |
| carrier.py:21 | TAINT_CARRIER_SOURCE | carrier.py:21 | Taint explicit.carrier | TAINT_CARRIER_SOURCE |
| carrier.py:22 | MethodCallsiteRefinement(c_0) | carrier.py:21 | Taint explicit.carrier | TAINT_CARRIER_SOURCE |
| carrier.py:25 | hub() | carrier.py:25 | Attribute 'attr' taint simple.test | hub() |
| carrier.py:29 | hub() | carrier.py:29 | Taint explicit.carrier | hub() |
| carrier.py:30 | MethodCallsiteRefinement(c_0) | carrier.py:29 | Taint explicit.carrier | hub() |
| carrier.py:33 | ImplicitCarrier() | carrier.py:33 | Attribute 'attr' taint explicit.carrier | ImplicitCarrier() |
| carrier.py:34 | Attribute | carrier.py:34 | Taint explicit.carrier | Attribute |
| carrier.py:35 | MethodCallsiteRefinement(x_0) | carrier.py:34 | Taint explicit.carrier | Attribute |
| deep.py:2 | ParameterDefinition | deep.py:2 | Taint simple.test | arg |
| deep.py:5 | ParameterDefinition | deep.py:5 | Taint simple.test | arg |
| deep.py:6 | ArgumentRefinement(arg_0) | deep.py:5 | Taint simple.test | arg |
| deep.py:8 | ParameterDefinition | deep.py:8 | Taint simple.test | arg |
| deep.py:9 | ArgumentRefinement(arg_0) | deep.py:8 | Taint simple.test | arg |
| deep.py:11 | ParameterDefinition | deep.py:11 | Taint simple.test | arg |
| deep.py:12 | ArgumentRefinement(arg_0) | deep.py:11 | Taint simple.test | arg |
| deep.py:14 | ParameterDefinition | deep.py:14 | Taint simple.test | arg |
| deep.py:15 | ArgumentRefinement(arg_0) | deep.py:14 | Taint simple.test | arg |
| deep.py:17 | ParameterDefinition | deep.py:17 | Taint simple.test | arg |
| deep.py:18 | ArgumentRefinement(arg_0) | deep.py:17 | Taint simple.test | arg |
| deep.py:20 | f6() | deep.py:20 | Taint simple.test | f6() |
| module.py:3 | SOURCE | module.py:3 | Taint simple.test | SOURCE |
| rockpaperscissors.py:3 | ParameterDefinition | rockpaperscissors.py:3 | Taint scissors | arg |
| rockpaperscissors.py:6 | ParameterDefinition | rockpaperscissors.py:6 | Taint paper | arg |
| rockpaperscissors.py:6 | ParameterDefinition | rockpaperscissors.py:6 | Taint rock | arg |
| rockpaperscissors.py:6 | ParameterDefinition | rockpaperscissors.py:6 | Taint scissors | arg |
| rockpaperscissors.py:9 | ParameterDefinition | rockpaperscissors.py:9 | Taint paper | arg |
| rockpaperscissors.py:9 | ParameterDefinition | rockpaperscissors.py:9 | Taint scissors | arg |
| rockpaperscissors.py:19 | ROCK | rockpaperscissors.py:19 | Taint rock | ROCK |
| rockpaperscissors.py:20 | Attribute() | rockpaperscissors.py:20 | Taint scissors | Attribute() |
| rockpaperscissors.py:20 | MethodCallsiteRefinement(x_0) | rockpaperscissors.py:19 | Taint rock | ROCK |
| rockpaperscissors.py:21 | ArgumentRefinement(y_0) | rockpaperscissors.py:20 | Taint scissors | Attribute() |
| rockpaperscissors.py:24 | ROCK | rockpaperscissors.py:24 | Taint rock | ROCK |
| rockpaperscissors.py:25 | Attribute() | rockpaperscissors.py:25 | Taint paper | Attribute() |
| rockpaperscissors.py:25 | MethodCallsiteRefinement(x_0) | rockpaperscissors.py:24 | Taint rock | ROCK |
| rockpaperscissors.py:26 | ArgumentRefinement(y_0) | rockpaperscissors.py:25 | Taint paper | Attribute() |
| rockpaperscissors.py:29 | SCISSORS | rockpaperscissors.py:29 | Taint scissors | SCISSORS |
| rockpaperscissors.py:30 | Attribute() | rockpaperscissors.py:30 | Taint paper | Attribute() |
| rockpaperscissors.py:30 | MethodCallsiteRefinement(x_0) | rockpaperscissors.py:29 | Taint scissors | SCISSORS |
| rockpaperscissors.py:31 | ArgumentRefinement(x_1) | rockpaperscissors.py:29 | Taint scissors | SCISSORS |
| rockpaperscissors.py:32 | ArgumentRefinement(y_0) | rockpaperscissors.py:30 | Taint paper | Attribute() |
| sanitizer.py:3 | ParameterDefinition | sanitizer.py:3 | Taint Command injection | arg |
| sanitizer.py:3 | ParameterDefinition | sanitizer.py:3 | Taint SQL injection | arg |
| sanitizer.py:5 | ParameterDefinition | sanitizer.py:5 | Taint Command injection | arg |
| sanitizer.py:5 | ParameterDefinition | sanitizer.py:5 | Taint SQL injection | arg |
| sanitizer.py:8 | phi(x_3, x_5) | sanitizer.py:9 | Taint Command injection | user_input() |
| sanitizer.py:8 | phi(x_3, x_5) | sanitizer.py:9 | Taint SQL injection | user_input() |
| sanitizer.py:9 | user_input() | sanitizer.py:9 | Taint Command injection | user_input() |
| sanitizer.py:9 | user_input() | sanitizer.py:9 | Taint SQL injection | user_input() |
| sanitizer.py:10 | ArgumentRefinement(x_0) | sanitizer.py:9 | Taint Command injection | user_input() |
| sanitizer.py:10 | ArgumentRefinement(x_0) | sanitizer.py:9 | Taint SQL injection | user_input() |
| sanitizer.py:11 | ArgumentRefinement(x_2) | sanitizer.py:9 | Taint Command injection | user_input() |
| sanitizer.py:11 | Pi(x_1) [true] | sanitizer.py:9 | Taint Command injection | user_input() |
| sanitizer.py:13 | ArgumentRefinement(x_4) | sanitizer.py:9 | Taint Command injection | user_input() |
| sanitizer.py:13 | ArgumentRefinement(x_4) | sanitizer.py:9 | Taint SQL injection | user_input() |
| sanitizer.py:13 | Pi(x_1) [false] | sanitizer.py:9 | Taint Command injection | user_input() |
| sanitizer.py:13 | Pi(x_1) [false] | sanitizer.py:9 | Taint SQL injection | user_input() |
| sanitizer.py:15 | phi(x_3, x_5) | sanitizer.py:16 | Taint Command injection | user_input() |
| sanitizer.py:15 | phi(x_3, x_5) | sanitizer.py:16 | Taint SQL injection | user_input() |
| sanitizer.py:16 | user_input() | sanitizer.py:16 | Taint Command injection | user_input() |
| sanitizer.py:16 | user_input() | sanitizer.py:16 | Taint SQL injection | user_input() |
| sanitizer.py:17 | ArgumentRefinement(x_0) | sanitizer.py:16 | Taint Command injection | user_input() |
| sanitizer.py:17 | ArgumentRefinement(x_0) | sanitizer.py:16 | Taint SQL injection | user_input() |
| sanitizer.py:18 | ArgumentRefinement(x_2) | sanitizer.py:16 | Taint SQL injection | user_input() |
| sanitizer.py:18 | Pi(x_1) [true] | sanitizer.py:16 | Taint SQL injection | user_input() |
| sanitizer.py:20 | ArgumentRefinement(x_4) | sanitizer.py:16 | Taint Command injection | user_input() |
| sanitizer.py:20 | ArgumentRefinement(x_4) | sanitizer.py:16 | Taint SQL injection | user_input() |
| sanitizer.py:20 | Pi(x_1) [false] | sanitizer.py:16 | Taint Command injection | user_input() |
| sanitizer.py:20 | Pi(x_1) [false] | sanitizer.py:16 | Taint SQL injection | user_input() |
| sanitizer.py:23 | phi(x_3, x_5) | sanitizer.py:24 | Taint Command injection | user_input() |
| sanitizer.py:23 | phi(x_3, x_5) | sanitizer.py:24 | Taint SQL injection | user_input() |
| sanitizer.py:24 | user_input() | sanitizer.py:24 | Taint Command injection | user_input() |
| sanitizer.py:24 | user_input() | sanitizer.py:24 | Taint SQL injection | user_input() |
| sanitizer.py:25 | ArgumentRefinement(x_0) | sanitizer.py:24 | Taint Command injection | user_input() |
| sanitizer.py:25 | ArgumentRefinement(x_0) | sanitizer.py:24 | Taint SQL injection | user_input() |
| sanitizer.py:26 | ArgumentRefinement(x_2) | sanitizer.py:24 | Taint Command injection | user_input() |
| sanitizer.py:26 | ArgumentRefinement(x_2) | sanitizer.py:24 | Taint SQL injection | user_input() |
| sanitizer.py:26 | Pi(x_1) [true] | sanitizer.py:24 | Taint Command injection | user_input() |
| sanitizer.py:26 | Pi(x_1) [true] | sanitizer.py:24 | Taint SQL injection | user_input() |
| sanitizer.py:28 | ArgumentRefinement(x_4) | sanitizer.py:24 | Taint Command injection | user_input() |
| sanitizer.py:28 | ArgumentRefinement(x_4) | sanitizer.py:24 | Taint SQL injection | user_input() |
| sanitizer.py:28 | Pi(x_1) [false] | sanitizer.py:24 | Taint Command injection | user_input() |
| sanitizer.py:28 | Pi(x_1) [false] | sanitizer.py:24 | Taint SQL injection | user_input() |
| sanitizer.py:30 | phi(x_3, x_5) | sanitizer.py:31 | Taint Command injection | user_input() |
| sanitizer.py:30 | phi(x_3, x_5) | sanitizer.py:31 | Taint SQL injection | user_input() |
| sanitizer.py:31 | user_input() | sanitizer.py:31 | Taint Command injection | user_input() |
| sanitizer.py:31 | user_input() | sanitizer.py:31 | Taint SQL injection | user_input() |
| sanitizer.py:32 | ArgumentRefinement(x_0) | sanitizer.py:31 | Taint Command injection | user_input() |
| sanitizer.py:32 | ArgumentRefinement(x_0) | sanitizer.py:31 | Taint SQL injection | user_input() |
| sanitizer.py:33 | ArgumentRefinement(x_2) | sanitizer.py:31 | Taint Command injection | user_input() |
| sanitizer.py:33 | ArgumentRefinement(x_2) | sanitizer.py:31 | Taint SQL injection | user_input() |
| sanitizer.py:33 | Pi(x_1) [true] | sanitizer.py:31 | Taint Command injection | user_input() |
| sanitizer.py:33 | Pi(x_1) [true] | sanitizer.py:31 | Taint SQL injection | user_input() |
| sanitizer.py:35 | ArgumentRefinement(x_4) | sanitizer.py:31 | Taint Command injection | user_input() |
| sanitizer.py:35 | ArgumentRefinement(x_4) | sanitizer.py:31 | Taint SQL injection | user_input() |
| sanitizer.py:35 | Pi(x_1) [false] | sanitizer.py:31 | Taint Command injection | user_input() |
| sanitizer.py:35 | Pi(x_1) [false] | sanitizer.py:31 | Taint SQL injection | user_input() |
| test.py:6 | SOURCE | test.py:6 | Taint simple.test | SOURCE |
| test.py:7 | ArgumentRefinement(s_0) | test.py:6 | Taint simple.test | SOURCE |
| test.py:12 | ParameterDefinition | test.py:12 | Taint simple.test | arg |
| test.py:13 | ArgumentRefinement(arg_0) | test.py:12 | Taint simple.test | arg |
| test.py:16 | source() | test.py:16 | Taint simple.test | source() |
| test.py:17 | ArgumentRefinement(t_0) | test.py:16 | Taint simple.test | source() |
| test.py:20 | SOURCE | test.py:20 | Taint simple.test | SOURCE |
| test.py:21 | ArgumentRefinement(t_0) | test.py:20 | Taint simple.test | SOURCE |
| test.py:24 | source() | test.py:24 | Taint simple.test | source() |
| test.py:25 | ArgumentRefinement(t_0) | test.py:24 | Taint simple.test | source() |
| test.py:31 | SOURCE | test.py:31 | Taint simple.test | SOURCE |
| test.py:37 | SOURCE | test.py:37 | Taint simple.test | SOURCE |
| test.py:41 | ArgumentRefinement(t_0) | test.py:37 | Taint simple.test | SOURCE |
| test.py:46 | ParameterDefinition | test.py:46 | Taint simple.test | arg |
| test.py:47 | ArgumentRefinement(arg_0) | test.py:46 | Taint simple.test | arg |
| test.py:49 | ParameterDefinition | test.py:49 | Taint simple.test | arg |
| test.py:49 | phi(arg_0, arg_1) | test.py:49 | Taint simple.test | arg |
| test.py:51 | ArgumentRefinement(arg_0) | test.py:49 | Taint simple.test | arg |
| test.py:54 | source2() | test.py:54 | Taint simple.test | source2() |
| test.py:55 | ArgumentRefinement(t_0) | test.py:54 | Taint simple.test | source2() |
| test.py:62 | SOURCE | test.py:62 | Taint simple.test | SOURCE |
| test.py:63 | phi(t_0, t_1) | test.py:62 | Taint simple.test | SOURCE |
| test.py:67 | SOURCE | test.py:67 | Taint simple.test | SOURCE |
| test.py:70 | phi(t_0, t_1) | test.py:67 | Taint simple.test | SOURCE |
| test.py:72 | ParameterDefinition | test.py:72 | Attribute 'x' taint simple.test | arg |
| test.py:72 | ParameterDefinition | test.py:72 | Taint basic.custom | arg |
| test.py:72 | ParameterDefinition | test.py:72 | Taint simple.test | arg |
| test.py:76 | SOURCE | test.py:76 | Taint simple.test | SOURCE |
| test.py:77 | hub() | test.py:77 | Taint simple.test | hub() |
| test.py:78 | ArgumentRefinement(t_1) | test.py:77 | Taint simple.test | hub() |
| test.py:85 | ImportExpr | test.py:85 | Attribute 'dangerous' taint simple.test | ImportExpr |
| test.py:87 | ScopeEntryDefinition | test.py:85 | Attribute 'dangerous' taint simple.test | ImportExpr |
| test.py:88 | Attribute | test.py:88 | Taint simple.test | Attribute |
| test.py:89 | ArgumentRefinement(t_0) | test.py:88 | Taint simple.test | Attribute |
| test.py:91 | ScopeEntryDefinition | test.py:85 | Attribute 'dangerous' taint simple.test | ImportExpr |
| test.py:95 | ScopeEntryDefinition | test.py:85 | Attribute 'dangerous' taint simple.test | ImportExpr |
| test.py:99 | ScopeEntryDefinition | test.py:85 | Attribute 'dangerous' taint simple.test | ImportExpr |
| test.py:100 | Attribute() | test.py:100 | Taint simple.test | Attribute() |
| test.py:101 | ArgumentRefinement(t_0) | test.py:100 | Taint simple.test | Attribute() |
| test.py:105 | ParameterDefinition | test.py:105 | Attribute 'x' taint simple.test | arg |
| test.py:108 | ScopeEntryDefinition | test.py:85 | Attribute 'dangerous' taint simple.test | ImportExpr |
| test.py:110 | AttributeAssignment 'x'(t_0) | test.py:110 | Attribute 'x' taint simple.test | t |
| test.py:113 | ScopeEntryDefinition | test.py:85 | Attribute 'dangerous' taint simple.test | ImportExpr |
| test.py:115 | AttributeAssignment 'x'(t_0) | test.py:115 | Attribute 'x' taint simple.test | t |
| test.py:116 | hub() | test.py:116 | Attribute 'x' taint simple.test | hub() |
| test.py:117 | ArgumentRefinement(t_2) | test.py:116 | Attribute 'x' taint simple.test | hub() |
| test.py:120 | CUSTOM_SOURCE | test.py:120 | Taint basic.custom | CUSTOM_SOURCE |
| test.py:121 | hub() | test.py:121 | Taint basic.custom | hub() |
| test.py:122 | ArgumentRefinement(t_1) | test.py:121 | Taint basic.custom | hub() |
| test.py:126 | CUSTOM_SOURCE | test.py:126 | Taint basic.custom | CUSTOM_SOURCE |
| test.py:128 | SOURCE | test.py:128 | Taint simple.test | SOURCE |
| test.py:130 | ArgumentRefinement(t_0) | test.py:126 | Taint basic.custom | CUSTOM_SOURCE |
| test.py:132 | ArgumentRefinement(t_2) | test.py:128 | Taint simple.test | SOURCE |
| test.py:136 | CUSTOM_SOURCE | test.py:136 | Taint basic.custom | CUSTOM_SOURCE |
| test.py:138 | SOURCE | test.py:138 | Taint simple.test | SOURCE |
| test.py:140 | ArgumentRefinement(t_2) | test.py:138 | Taint simple.test | SOURCE |
| test.py:142 | ArgumentRefinement(t_0) | test.py:136 | Taint basic.custom | CUSTOM_SOURCE |
| test.py:146 | CUSTOM_SOURCE | test.py:146 | Taint basic.custom | CUSTOM_SOURCE |
| test.py:148 | SOURCE | test.py:148 | Taint simple.test | SOURCE |
| test.py:149 | TAINT_FROM_ARG() | test.py:149 | Taint basic.custom | TAINT_FROM_ARG() |
| test.py:151 | ArgumentRefinement(t_1) | test.py:149 | Taint basic.custom | TAINT_FROM_ARG() |
| test.py:155 | ImportMember | test.py:155 | Taint simple.test | ImportMember |
| test.py:156 | ArgumentRefinement(unsafe_0) | test.py:155 | Taint simple.test | ImportMember |
| test.py:159 | with | test.py:159 | Taint simple.test | SOURCE |
| test.py:160 | ArgumentRefinement(t_0) | test.py:159 | Taint simple.test | SOURCE |
| test.py:163 | SOURCE | test.py:163 | Taint simple.test | SOURCE |
| test.py:168 | List | test.py:168 | Taint [simple.test] | List |
| test.py:169 | Dict | test.py:169 | Taint {simple.test} | Dict |
| test.py:170 | ArgumentRefinement(l_0) | test.py:168 | Taint [simple.test] | List |
| test.py:171 | ArgumentRefinement(d_0) | test.py:169 | Taint {simple.test} | Dict |
| test.py:174 | ArgumentRefinement(l_1) | test.py:168 | Taint [simple.test] | List |
| test.py:174 | list() | test.py:174 | Taint [simple.test] | list() |
| test.py:175 | ArgumentRefinement(d_1) | test.py:169 | Taint {simple.test} | Dict |
| test.py:175 | dict() | test.py:175 | Taint {simple.test} | dict() |
| test.py:178 | SOURCE | test.py:178 | Taint simple.test | SOURCE |
| test.py:180 | ArgumentRefinement(t_1) | test.py:178 | Taint simple.test | SOURCE |
| test.py:180 | Pi(t_0) [true] | test.py:178 | Taint simple.test | SOURCE |
| test.py:183 | SingleSuccessorGuard(t_2) [false] | test.py:178 | Taint simple.test | SOURCE |
| test.py:186 | ArgumentRefinement(t_3) | test.py:178 | Taint simple.test | SOURCE |
| test.py:189 | FALSEY | test.py:189 | Taint falsey | FALSEY |
| test.py:191 | Pi(t_0) [true] | test.py:189 | Taint falsey | FALSEY |

View File

@@ -0,0 +1,9 @@
import python
import semmle.python.security.TaintTest
import TaintLib
from EssaDefinition defn, TaintedNode n
where TaintFlowTest::tainted_def(defn, _, n)
select
defn.getLocation().toString(), defn.getRepresentation(), n.getLocation().toString(), n.getTrackedValue(), n.getNode().getNode().toString()

View File

@@ -94,6 +94,8 @@
| Taint explicit.carrier | carrier.py:33 | TAINT_CARRIER_SOURCE | |
| Taint explicit.carrier | carrier.py:34 | Attribute | |
| Taint explicit.carrier | carrier.py:35 | x | |
| Taint falsey | test.py:189 | FALSEY | |
| Taint falsey | test.py:190 | t | |
| Taint paper | rockpaperscissors.py:6 | arg | rockpaperscissors.py:32 |
| Taint paper | rockpaperscissors.py:9 | arg | rockpaperscissors.py:26 |
| Taint paper | rockpaperscissors.py:25 | Attribute() | |

View File

@@ -41,3 +41,4 @@
| test.py:168 | SOURCE | simple.test |
| test.py:169 | SOURCE | simple.test |
| test.py:178 | SOURCE | simple.test |
| test.py:189 | FALSEY | falsey |

View File

@@ -82,6 +82,7 @@
| Taint explicit.carrier | carrier.py:33 | TAINT_CARRIER_SOURCE | | --> | Taint explicit.carrier | carrier.py:4 | arg | carrier.py:33 |
| Taint explicit.carrier | carrier.py:34 | Attribute | | --> | Taint explicit.carrier | carrier.py:35 | x | |
| Taint explicit.carrier | carrier.py:35 | x | | --> | Taint simple.test | carrier.py:35 | Attribute() | |
| Taint falsey | test.py:189 | FALSEY | | --> | Taint falsey | test.py:190 | t | |
| Taint paper | rockpaperscissors.py:25 | Attribute() | | --> | Taint paper | rockpaperscissors.py:26 | y | |
| Taint paper | rockpaperscissors.py:26 | y | | --> | Taint paper | rockpaperscissors.py:9 | arg | rockpaperscissors.py:26 |
| Taint paper | rockpaperscissors.py:30 | Attribute() | | --> | Taint paper | rockpaperscissors.py:32 | y | |

View File

@@ -182,3 +182,5 @@
| test.py:180 | t_2 | test.py:178 | Taint simple.test | SOURCE |
| test.py:183 | t_3 | test.py:178 | Taint simple.test | SOURCE |
| test.py:186 | t_4 | test.py:178 | Taint simple.test | SOURCE |
| test.py:189 | t_0 | test.py:189 | Taint falsey | FALSEY |
| test.py:191 | t_1 | test.py:189 | Taint falsey | FALSEY |

View File

@@ -184,3 +184,9 @@ def test_truth():
SINK(t)
else:
SINK(t)
def test_early_exit():
t = FALSEY
if not t:
return
t