diff --git a/python/ql/test/3/library-tests/taint/strings/Taint.qll b/python/ql/test/3/library-tests/taint/strings/Taint.qll new file mode 100644 index 00000000000..3368a1c4f70 --- /dev/null +++ b/python/ql/test/3/library-tests/taint/strings/Taint.qll @@ -0,0 +1,44 @@ +import python +import semmle.python.dataflow.TaintTracking +import semmle.python.security.strings.Untrusted +import semmle.python.security.Exceptions + +class SimpleSource extends TaintSource { + SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" } + + override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } + + override string toString() { result = "taint source" } +} + +class ListSource extends TaintSource { + ListSource() { this.(NameNode).getId() = "TAINTED_LIST" } + + override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind } + + override string toString() { result = "list taint source" } +} + +class DictSource extends TaintSource { + DictSource() { this.(NameNode).getId() = "TAINTED_DICT" } + + override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind } + + override string toString() { result = "dict taint source" } +} + +class ExceptionInfoSource extends TaintSource { + ExceptionInfoSource() { this.(NameNode).getId() = "TAINTED_EXCEPTION_INFO" } + + override predicate isSourceOf(TaintKind kind) { kind instanceof ExceptionInfo } + + override string toString() { result = "Exception info source" } +} + +class ExternalFileObjectSource extends TaintSource { + ExternalFileObjectSource() { this.(NameNode).getId() = "TAINTED_FILE" } + + override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalFileObject } + + override string toString() { result = "Tainted file source" } +} diff --git a/python/ql/test/3/library-tests/taint/strings/TestTaint.expected b/python/ql/test/3/library-tests/taint/strings/TestTaint.expected new file mode 100644 index 00000000000..6135fb2a756 --- /dev/null +++ b/python/ql/test/3/library-tests/taint/strings/TestTaint.expected @@ -0,0 +1 @@ +| test.py:4 | fail | fstring | Fstring | | diff --git a/python/ql/test/3/library-tests/taint/strings/TestTaint.ql b/python/ql/test/3/library-tests/taint/strings/TestTaint.ql new file mode 100644 index 00000000000..7b9c6025c9d --- /dev/null +++ b/python/ql/test/3/library-tests/taint/strings/TestTaint.ql @@ -0,0 +1,33 @@ +import python +import semmle.python.security.TaintTracking +import semmle.python.web.HttpRequest +import semmle.python.security.strings.Untrusted +import Taint + +from + Call call, Expr arg, boolean expected_taint, boolean has_taint, string test_res, + string taint_string +where + call.getLocation().getFile().getShortName() = "test.py" and + ( + call.getFunc().(Name).getId() = "ensure_tainted" and + expected_taint = true + or + call.getFunc().(Name).getId() = "ensure_not_tainted" and + expected_taint = false + ) and + arg = call.getAnArg() and + ( + not exists(TaintedNode tainted | tainted.getAstNode() = arg) and + taint_string = "" and + has_taint = false + or + exists(TaintedNode tainted | tainted.getAstNode() = arg | + taint_string = tainted.getTaintKind().toString() + ) and + has_taint = true + ) and + if expected_taint = has_taint then test_res = "ok " else test_res = "fail" +// if expected_taint = has_taint then test_res = "✓" else test_res = "✕" +select arg.getLocation().toString(), test_res, call.getScope().(Function).getName(), arg.toString(), + taint_string diff --git a/python/ql/test/3/library-tests/taint/strings/test.py b/python/ql/test/3/library-tests/taint/strings/test.py new file mode 100644 index 00000000000..e1c25b5dccc --- /dev/null +++ b/python/ql/test/3/library-tests/taint/strings/test.py @@ -0,0 +1,5 @@ +def fstring(): + tainted_string = TAINTED_STRING + ensure_tainted( + f"foo {tainted_string} bar" + )