Skip to content

Commit be2acc0

Browse files
committed
Python: Add test for tainted f-string
1 parent 765c40e commit be2acc0

File tree

4 files changed

+83
-0
lines changed

4 files changed

+83
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import python
2+
import semmle.python.dataflow.TaintTracking
3+
import semmle.python.security.strings.Untrusted
4+
import semmle.python.security.Exceptions
5+
6+
class SimpleSource extends TaintSource {
7+
SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" }
8+
9+
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
10+
11+
override string toString() { result = "taint source" }
12+
}
13+
14+
class ListSource extends TaintSource {
15+
ListSource() { this.(NameNode).getId() = "TAINTED_LIST" }
16+
17+
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind }
18+
19+
override string toString() { result = "list taint source" }
20+
}
21+
22+
class DictSource extends TaintSource {
23+
DictSource() { this.(NameNode).getId() = "TAINTED_DICT" }
24+
25+
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind }
26+
27+
override string toString() { result = "dict taint source" }
28+
}
29+
30+
class ExceptionInfoSource extends TaintSource {
31+
ExceptionInfoSource() { this.(NameNode).getId() = "TAINTED_EXCEPTION_INFO" }
32+
33+
override predicate isSourceOf(TaintKind kind) { kind instanceof ExceptionInfo }
34+
35+
override string toString() { result = "Exception info source" }
36+
}
37+
38+
class ExternalFileObjectSource extends TaintSource {
39+
ExternalFileObjectSource() { this.(NameNode).getId() = "TAINTED_FILE" }
40+
41+
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalFileObject }
42+
43+
override string toString() { result = "Tainted file source" }
44+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| test.py:4 | fail | fstring | Fstring | <NO TAINT> |
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import python
2+
import semmle.python.security.TaintTracking
3+
import semmle.python.web.HttpRequest
4+
import semmle.python.security.strings.Untrusted
5+
import Taint
6+
7+
from
8+
Call call, Expr arg, boolean expected_taint, boolean has_taint, string test_res,
9+
string taint_string
10+
where
11+
call.getLocation().getFile().getShortName() = "test.py" and
12+
(
13+
call.getFunc().(Name).getId() = "ensure_tainted" and
14+
expected_taint = true
15+
or
16+
call.getFunc().(Name).getId() = "ensure_not_tainted" and
17+
expected_taint = false
18+
) and
19+
arg = call.getAnArg() and
20+
(
21+
not exists(TaintedNode tainted | tainted.getAstNode() = arg) and
22+
taint_string = "<NO TAINT>" and
23+
has_taint = false
24+
or
25+
exists(TaintedNode tainted | tainted.getAstNode() = arg |
26+
taint_string = tainted.getTaintKind().toString()
27+
) and
28+
has_taint = true
29+
) and
30+
if expected_taint = has_taint then test_res = "ok " else test_res = "fail"
31+
// if expected_taint = has_taint then test_res = "✓" else test_res = "✕"
32+
select arg.getLocation().toString(), test_res, call.getScope().(Function).getName(), arg.toString(),
33+
taint_string
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
def fstring():
2+
tainted_string = TAINTED_STRING
3+
ensure_tainted(
4+
f"foo {tainted_string} bar"
5+
)

0 commit comments

Comments
 (0)