From 722d89fc7502e4490c0c7dcb62c1eca4dc41abfb Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 23 Feb 2018 16:19:39 +0000 Subject: [PATCH 1/8] Upgrade taint-tracking security queries to path-problem queries. --- .../ql/src/Security/CWE-022/PathInjection.ql | 10 +++++--- .../src/Security/CWE-078/CommandInjection.ql | 9 ++++--- .../ql/src/Security/CWE-079/ReflectedXss.ql | 9 ++++--- .../ql/src/Security/CWE-089/SqlInjection.ql | 9 ++++--- .../ql/src/Security/CWE-094/CodeInjection.ql | 9 ++++--- .../Security/CWE-209/StackTraceExposure.ql | 9 ++++--- .../Security/CWE-502/UnsafeDeserialization.ql | 9 ++++--- python/ql/src/Security/CWE-601/UrlRedirect.ql | 10 ++++---- .../semmle/python/security/TaintTracking.qll | 21 ++++++++++++++++ .../semmle/python/security/Paths.qll | 25 +++++++++++++++++++ 10 files changed, 87 insertions(+), 33 deletions(-) create mode 100644 semmlecode-python-queries/semmle/python/security/Paths.qll diff --git a/python/ql/src/Security/CWE-022/PathInjection.ql b/python/ql/src/Security/CWE-022/PathInjection.ql index 5d5561e49c35..0d54ffc7ff1c 100644 --- a/python/ql/src/Security/CWE-022/PathInjection.ql +++ b/python/ql/src/Security/CWE-022/PathInjection.ql @@ -1,7 +1,7 @@ /** * @name Uncontrolled data used in path expression * @description Accessing paths influenced by users can allow an attacker to access unexpected resources. - * @kind problem + * @kind path-problem * @problem.severity error * @sub-severity high * @precision high @@ -17,6 +17,7 @@ */ import python +import semmle.python.security.Paths /* Sources */ import semmle.python.web.HttpRequest @@ -25,7 +26,8 @@ import semmle.python.web.HttpRequest import semmle.python.security.injection.Path -from TaintSource src, TaintSink sink -where src.flowsToSink(sink) -select sink, "This path depends on $@.", src, "a user-provided value" +from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink +where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink + +select sink, srcnode, sinknode, "This path depends on $@.", src, "a user-provided value" diff --git a/python/ql/src/Security/CWE-078/CommandInjection.ql b/python/ql/src/Security/CWE-078/CommandInjection.ql index 44e9d56dda36..260f1a8c2440 100755 --- a/python/ql/src/Security/CWE-078/CommandInjection.ql +++ b/python/ql/src/Security/CWE-078/CommandInjection.ql @@ -2,7 +2,7 @@ * @name Uncontrolled command line * @description Using externally controlled strings in a command line may allow a malicious * user to change the meaning of the command. - * @kind problem + * @kind path-problem * @problem.severity error * @sub-severity high * @precision high @@ -15,6 +15,7 @@ */ import python +import semmle.python.security.Paths /* Sources */ import semmle.python.web.HttpRequest @@ -22,7 +23,7 @@ import semmle.python.web.HttpRequest /* Sinks */ import semmle.python.security.injection.Command -from TaintSource src, TaintSink sink -where src.flowsToSink(sink) +from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink +where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink -select sink, "This command depends on $@.", src, "a user-provided value" +select sink, srcnode, sinknode, "This command depends on $@.", src, "a user-provided value" diff --git a/python/ql/src/Security/CWE-079/ReflectedXss.ql b/python/ql/src/Security/CWE-079/ReflectedXss.ql index dff7657a7184..28a59b71d418 100644 --- a/python/ql/src/Security/CWE-079/ReflectedXss.ql +++ b/python/ql/src/Security/CWE-079/ReflectedXss.ql @@ -2,7 +2,7 @@ * @name Reflected server-side cross-site scripting * @description Writing user input directly to a web page * allows for a cross-site scripting vulnerability. - * @kind problem + * @kind path-problem * @problem.severity error * @sub-severity high * @precision high @@ -13,6 +13,7 @@ */ import python +import semmle.python.security.Paths /* Sources */ import semmle.python.web.HttpRequest @@ -24,9 +25,9 @@ import semmle.python.web.HttpResponse /* Flow */ import semmle.python.security.strings.Untrusted -from TaintSource src, TaintSink sink -where src.flowsToSink(sink) +from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink +where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink -select sink, "Cross-site scripting vulnerability due to $@.", +select sink, srcnode, sinknode, "Cross-site scripting vulnerability due to $@.", src, "user-provided value" diff --git a/python/ql/src/Security/CWE-089/SqlInjection.ql b/python/ql/src/Security/CWE-089/SqlInjection.ql index 0513bb6ba1f3..9189417ad475 100755 --- a/python/ql/src/Security/CWE-089/SqlInjection.ql +++ b/python/ql/src/Security/CWE-089/SqlInjection.ql @@ -2,7 +2,7 @@ * @name SQL query built from user-controlled sources * @description Building a SQL query from user-controlled sources is vulnerable to insertion of * malicious SQL code by the user. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id py/sql-injection @@ -12,6 +12,7 @@ */ import python +import semmle.python.security.Paths /* Sources */ import semmle.python.web.HttpRequest @@ -22,7 +23,7 @@ import semmle.python.web.django.Db import semmle.python.web.django.Model -from TaintSource src, TaintSink sink -where src.flowsToSink(sink) +from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink +where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink -select sink, "This SQL query depends on $@.", src, "a user-provided value" +select sink, srcnode, sinknode, "This SQL query depends on $@.", src, "a user-provided value" diff --git a/python/ql/src/Security/CWE-094/CodeInjection.ql b/python/ql/src/Security/CWE-094/CodeInjection.ql index 12b816736eb3..e0d5acaba3e8 100644 --- a/python/ql/src/Security/CWE-094/CodeInjection.ql +++ b/python/ql/src/Security/CWE-094/CodeInjection.ql @@ -2,7 +2,7 @@ * @name Code injection * @description Interpreting unsanitized user input as code allows a malicious user arbitrary * code execution. - * @kind problem + * @kind path-problem * @problem.severity error * @sub-severity high * @precision high @@ -15,6 +15,7 @@ */ import python +import semmle.python.security.Paths /* Sources */ import semmle.python.web.HttpRequest @@ -23,7 +24,7 @@ import semmle.python.web.HttpRequest import semmle.python.security.injection.Exec -from TaintSource src, TaintSink sink -where src.flowsToSink(sink) +from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink +where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink -select sink, "$@ flows to here and is interpreted as code.", src, "User-provided value" +select sink, srcnode, sinknode, "$@ flows to here and is interpreted as code.", src, "User-provided value" diff --git a/python/ql/src/Security/CWE-209/StackTraceExposure.ql b/python/ql/src/Security/CWE-209/StackTraceExposure.ql index f389cb6cc305..c22a744b7b64 100644 --- a/python/ql/src/Security/CWE-209/StackTraceExposure.ql +++ b/python/ql/src/Security/CWE-209/StackTraceExposure.ql @@ -3,7 +3,7 @@ * @description Leaking information about an exception, such as messages and stack traces, to an * external user can expose implementation details that are useful to an attacker for * developing a subsequent exploit. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id py/stack-trace-exposure @@ -13,10 +13,11 @@ */ import python +import semmle.python.security.Paths import semmle.python.security.Exceptions import semmle.python.web.HttpResponse -from TaintSource src, TaintSink sink -where src.flowsToSink(sink) -select sink, "$@ may be exposed to an external user", src, "Error information" +from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink +where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink +select sink, srcnode, sinknode, "$@ may be exposed to an external user", src, "Error information" diff --git a/python/ql/src/Security/CWE-502/UnsafeDeserialization.ql b/python/ql/src/Security/CWE-502/UnsafeDeserialization.ql index af7a906691db..32ce6fa8361c 100644 --- a/python/ql/src/Security/CWE-502/UnsafeDeserialization.ql +++ b/python/ql/src/Security/CWE-502/UnsafeDeserialization.ql @@ -1,7 +1,7 @@ /** * @name Deserializing untrusted input * @description Deserializing user-controlled data may allow attackers to execute arbitrary code. - * @kind problem + * @kind path-problem * @id py/unsafe-deserialization * @problem.severity error * @sub-severity high @@ -14,6 +14,7 @@ import python // Sources -- Any untrusted input import semmle.python.web.HttpRequest +import semmle.python.security.Paths // Flow -- untrusted string import semmle.python.security.strings.Untrusted @@ -23,8 +24,8 @@ import semmle.python.security.injection.Pickle import semmle.python.security.injection.Marshal import semmle.python.security.injection.Yaml -from TaintSource src, TaintSink sink -where src.flowsToSink(sink) +from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink +where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink -select sink, "Deserializing of $@.", src, "untrusted input" +select sink, srcnode, sinknode, "Deserializing of $@.", src, "untrusted input" diff --git a/python/ql/src/Security/CWE-601/UrlRedirect.ql b/python/ql/src/Security/CWE-601/UrlRedirect.ql index 6a412813bc09..9ff1723aab11 100644 --- a/python/ql/src/Security/CWE-601/UrlRedirect.ql +++ b/python/ql/src/Security/CWE-601/UrlRedirect.ql @@ -2,7 +2,7 @@ * @name URL redirection from remote source * @description URL redirection based on unvalidated user input * may cause redirection to malicious web sites. - * @kind problem + * @kind path-problem * @problem.severity error * @sub-severity low * @id py/url-redirection @@ -12,7 +12,7 @@ */ import python - +import semmle.python.security.Paths import semmle.python.web.HttpRedirect import semmle.python.web.HttpRequest @@ -28,8 +28,8 @@ class UntrustedPrefixStringKind extends UntrustedStringKind { } -from TaintSource src, TaintSink sink -where src.flowsToSink(sink) +from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink +where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink -select sink, "Untrusted URL redirection due to $@.", src, "a user-provided value" +select sink, srcnode, sinknode, "Untrusted URL redirection due to $@.", src, "a user-provided value" diff --git a/python/ql/src/semmle/python/security/TaintTracking.qll b/python/ql/src/semmle/python/security/TaintTracking.qll index 90620ca14ba8..d8dd0ea143f9 100755 --- a/python/ql/src/semmle/python/security/TaintTracking.qll +++ b/python/ql/src/semmle/python/security/TaintTracking.qll @@ -675,6 +675,27 @@ class TaintedNode extends TTaintedNode { } +class TaintedNodeSource extends TaintedNode { + + TaintedNodeSource() { + this.getNode().(TaintSource).isSourceOf(this.getTaintKind(), this.getContext()) + } + + /** Holds if taint can flow from this source to sink `sink` */ + final predicate flowsTo(TaintedNodeSink sink) { + this.getASuccessor*() = sink + } + +} + +class TaintedNodeSink extends TaintedNode { + + TaintedNodeSink() { + this.getNode().(TaintSink).sinks(this.getTaintKind()) + } + +} + /** This module contains the implementation of taint-flow. * It is recommended that users use the `TaintedNode` class, rather than using this module directly * as the interface of this module may change without warning. diff --git a/semmlecode-python-queries/semmle/python/security/Paths.qll b/semmlecode-python-queries/semmle/python/security/Paths.qll new file mode 100644 index 000000000000..09f88ecf5f35 --- /dev/null +++ b/semmlecode-python-queries/semmle/python/security/Paths.qll @@ -0,0 +1,25 @@ +import python + +import semmle.python.security.TaintTracking + +query predicate edges(TaintedNode fromnode, TaintedNode tonode) { + fromnode.getASuccessor() = tonode +} + +private TaintedNode first_child(TaintedNode parent) { + result.getContext().getCaller() = parent.getContext() and + parent.getASuccessor() = result +} + +private TaintedNode next_sibling(TaintedNode child) { + child.getASuccessor() = result and + child.getContext() = result.getContext() +} + +query predicate parents(TaintedNode child, TaintedNode parent) { + child = first_child(parent) or + exists(TaintedNode prev | + parents(prev, parent) and + child = next_sibling(child) + ) +} From 2a24723cc3f45eca61242402ff8d6abccc95b7af Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 16 Nov 2018 14:17:07 +0000 Subject: [PATCH 2/8] Python: Update test results for path queries. --- .../Security/CWE-022/PathInjection.expected | 57 ++++++++++++++++++- .../CWE-078/CommandInjection.expected | 22 ++++++- .../Security/CWE-079/ReflectedXss.expected | 14 ++++- .../Security/CWE-089/SqlInjection.expected | 17 ++++-- .../Security/CWE-094/CodeInjection.expected | 13 ++++- .../CWE-502/UnsafeDeserialization.expected | 15 ++++- .../Security/CWE-601/UrlRedirect.expected | 11 +++- .../query-tests/Security/lib/base64.py | 2 + .../query-tests/Security/lib/marshall.py | 2 + .../query-tests/Security/lib/os/__init__.py | 2 + .../query-tests/Security/lib/os/path.py | 5 ++ .../query-tests/Security/lib/pickle.py | 2 + .../query-tests/Security/lib/subprocess.py | 2 + .../query-tests/Security/lib/traceback.py | 2 + 14 files changed, 150 insertions(+), 16 deletions(-) create mode 100644 semmlecode-python-tests/query-tests/Security/lib/base64.py create mode 100644 semmlecode-python-tests/query-tests/Security/lib/marshall.py create mode 100644 semmlecode-python-tests/query-tests/Security/lib/os/__init__.py create mode 100644 semmlecode-python-tests/query-tests/Security/lib/os/path.py create mode 100644 semmlecode-python-tests/query-tests/Security/lib/pickle.py create mode 100644 semmlecode-python-tests/query-tests/Security/lib/subprocess.py create mode 100644 semmlecode-python-tests/query-tests/Security/lib/traceback.py diff --git a/python/ql/test/query-tests/Security/CWE-022/PathInjection.expected b/python/ql/test/query-tests/Security/CWE-022/PathInjection.expected index 68979df27ed6..d6791fde69bd 100644 --- a/python/ql/test/query-tests/Security/CWE-022/PathInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-022/PathInjection.expected @@ -1,3 +1,54 @@ -| path_injection.py:10:14:10:44 | argument to open() | This path depends on $@. | path_injection.py:9:12:9:23 | flask.request.args | a user-provided value | -| path_injection.py:17:14:17:18 | argument to open() | This path depends on $@. | path_injection.py:15:12:15:23 | flask.request.args | a user-provided value | -| path_injection.py:28:14:28:18 | argument to open() | This path depends on $@. | path_injection.py:24:12:24:23 | flask.request.args | a user-provided value | +edges +| ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | ../lib/os/path.py:2:22:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | +| ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | ../lib/os/path.py:2:22:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | +| ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | ../lib/os/path.py:2:22:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | +| ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | ../lib/os/path.py:2:22:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | +| ../lib/os/path.py:2:12:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | path_injection.py:10:14:10:44 | Taint externally controlled string at path_injection.py:10 | +| ../lib/os/path.py:2:12:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | path_injection.py:16:30:16:60 | Taint externally controlled string at path_injection.py:16 | +| ../lib/os/path.py:2:12:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | path_injection.py:25:30:25:60 | Taint externally controlled string at path_injection.py:25 | +| ../lib/os/path.py:2:12:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | path_injection.py:34:30:34:60 | Taint externally controlled string at path_injection.py:34 | +| ../lib/os/path.py:2:22:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | ../lib/os/path.py:2:12:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | +| ../lib/os/path.py:2:22:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | ../lib/os/path.py:2:12:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | +| ../lib/os/path.py:2:22:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | ../lib/os/path.py:2:12:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | +| ../lib/os/path.py:2:22:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | ../lib/os/path.py:2:12:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | +| ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | ../lib/os/path.py:5:12:5:12 | Taint externally controlled string at ../lib/os/path.py:5 | +| ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | ../lib/os/path.py:5:12:5:12 | Taint externally controlled string at ../lib/os/path.py:5 | +| ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | ../lib/os/path.py:5:12:5:12 | Taint externally controlled string at ../lib/os/path.py:5 | +| path_injection.py:9:12:9:23 | Taint {externally controlled string} at path_injection.py:9 | path_injection.py:9:12:9:39 | Taint externally controlled string at path_injection.py:9 | +| path_injection.py:9:12:9:39 | Taint externally controlled string at path_injection.py:9 | path_injection.py:10:40:10:43 | Taint externally controlled string at path_injection.py:10 | +| path_injection.py:10:40:10:43 | Taint externally controlled string at path_injection.py:10 | ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | +| path_injection.py:10:40:10:43 | Taint externally controlled string at path_injection.py:10 | path_injection.py:10:14:10:44 | Taint externally controlled string at path_injection.py:10 | +| path_injection.py:15:12:15:23 | Taint {externally controlled string} at path_injection.py:15 | path_injection.py:15:12:15:39 | Taint externally controlled string at path_injection.py:15 | +| path_injection.py:15:12:15:39 | Taint externally controlled string at path_injection.py:15 | path_injection.py:16:56:16:59 | Taint externally controlled string at path_injection.py:16 | +| path_injection.py:16:13:16:61 | Taint normalized.path.injection at path_injection.py:16 | path_injection.py:17:14:17:18 | Taint normalized.path.injection at path_injection.py:17 | +| path_injection.py:16:30:16:60 | Taint externally controlled string at path_injection.py:16 | ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | +| path_injection.py:16:30:16:60 | Taint externally controlled string at path_injection.py:16 | path_injection.py:16:13:16:61 | Taint normalized.path.injection at path_injection.py:16 | +| path_injection.py:16:56:16:59 | Taint externally controlled string at path_injection.py:16 | ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | +| path_injection.py:16:56:16:59 | Taint externally controlled string at path_injection.py:16 | path_injection.py:16:30:16:60 | Taint externally controlled string at path_injection.py:16 | +| path_injection.py:24:12:24:23 | Taint {externally controlled string} at path_injection.py:24 | path_injection.py:24:12:24:39 | Taint externally controlled string at path_injection.py:24 | +| path_injection.py:24:12:24:39 | Taint externally controlled string at path_injection.py:24 | path_injection.py:25:56:25:59 | Taint externally controlled string at path_injection.py:25 | +| path_injection.py:25:13:25:61 | Taint normalized.path.injection at path_injection.py:25 | path_injection.py:26:8:26:12 | Taint normalized.path.injection at path_injection.py:26 | +| path_injection.py:25:13:25:61 | Taint normalized.path.injection at path_injection.py:25 | path_injection.py:28:14:28:18 | Taint normalized.path.injection at path_injection.py:28 | +| path_injection.py:25:30:25:60 | Taint externally controlled string at path_injection.py:25 | ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | +| path_injection.py:25:30:25:60 | Taint externally controlled string at path_injection.py:25 | path_injection.py:25:13:25:61 | Taint normalized.path.injection at path_injection.py:25 | +| path_injection.py:25:56:25:59 | Taint externally controlled string at path_injection.py:25 | ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | +| path_injection.py:25:56:25:59 | Taint externally controlled string at path_injection.py:25 | path_injection.py:25:30:25:60 | Taint externally controlled string at path_injection.py:25 | +| path_injection.py:33:12:33:23 | Taint {externally controlled string} at path_injection.py:33 | path_injection.py:33:12:33:39 | Taint externally controlled string at path_injection.py:33 | +| path_injection.py:33:12:33:39 | Taint externally controlled string at path_injection.py:33 | path_injection.py:34:56:34:59 | Taint externally controlled string at path_injection.py:34 | +| path_injection.py:34:13:34:61 | Taint normalized.path.injection at path_injection.py:34 | path_injection.py:35:8:35:12 | Taint normalized.path.injection at path_injection.py:35 | +| path_injection.py:34:30:34:60 | Taint externally controlled string at path_injection.py:34 | ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | +| path_injection.py:34:30:34:60 | Taint externally controlled string at path_injection.py:34 | path_injection.py:34:13:34:61 | Taint normalized.path.injection at path_injection.py:34 | +| path_injection.py:34:56:34:59 | Taint externally controlled string at path_injection.py:34 | ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | +| path_injection.py:34:56:34:59 | Taint externally controlled string at path_injection.py:34 | path_injection.py:34:30:34:60 | Taint externally controlled string at path_injection.py:34 | +parents +| ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | path_injection.py:10:40:10:43 | Taint externally controlled string at path_injection.py:10 | +| ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | path_injection.py:16:56:16:59 | Taint externally controlled string at path_injection.py:16 | +| ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | path_injection.py:25:56:25:59 | Taint externally controlled string at path_injection.py:25 | +| ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | path_injection.py:34:56:34:59 | Taint externally controlled string at path_injection.py:34 | +| ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | path_injection.py:16:30:16:60 | Taint externally controlled string at path_injection.py:16 | +| ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | path_injection.py:25:30:25:60 | Taint externally controlled string at path_injection.py:25 | +| ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | path_injection.py:34:30:34:60 | Taint externally controlled string at path_injection.py:34 | +#select +| path_injection.py:10:14:10:44 | argument to open() | path_injection.py:9:12:9:23 | Taint {externally controlled string} at path_injection.py:9 | path_injection.py:10:14:10:44 | Taint externally controlled string at path_injection.py:10 | This path depends on $@. | path_injection.py:9:12:9:23 | flask.request.args | a user-provided value | +| path_injection.py:17:14:17:18 | argument to open() | path_injection.py:15:12:15:23 | Taint {externally controlled string} at path_injection.py:15 | path_injection.py:17:14:17:18 | Taint normalized.path.injection at path_injection.py:17 | This path depends on $@. | path_injection.py:15:12:15:23 | flask.request.args | a user-provided value | +| path_injection.py:28:14:28:18 | argument to open() | path_injection.py:24:12:24:23 | Taint {externally controlled string} at path_injection.py:24 | path_injection.py:28:14:28:18 | Taint normalized.path.injection at path_injection.py:28 | This path depends on $@. | path_injection.py:24:12:24:23 | flask.request.args | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-078/CommandInjection.expected b/python/ql/test/query-tests/Security/CWE-078/CommandInjection.expected index e48b14ad0aad..09953ec851eb 100644 --- a/python/ql/test/query-tests/Security/CWE-078/CommandInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-078/CommandInjection.expected @@ -1,3 +1,19 @@ -| command_injection.py:12:15:12:27 | shell command | This command depends on $@. | command_injection.py:10:13:10:24 | flask.request.args | a user-provided value | -| command_injection.py:19:22:19:34 | shell command | This command depends on $@. | command_injection.py:17:13:17:24 | flask.request.args | a user-provided value | -| command_injection.py:25:22:25:36 | OS command first argument | This command depends on $@. | command_injection.py:24:11:24:22 | flask.request.args | a user-provided value | +edges +| command_injection.py:10:13:10:24 | Taint {externally controlled string} at command_injection.py:10 | command_injection.py:10:13:10:41 | Taint externally controlled string at command_injection.py:10 | +| command_injection.py:10:13:10:41 | Taint externally controlled string at command_injection.py:10 | command_injection.py:12:23:12:27 | Taint externally controlled string at command_injection.py:12 | +| command_injection.py:12:15:12:27 | Taint externally controlled string at command_injection.py:12 | ../lib/os/__init__.py:1:12:1:14 | Taint externally controlled string at ../lib/os/__init__.py:1 | +| command_injection.py:12:23:12:27 | Taint externally controlled string at command_injection.py:12 | command_injection.py:12:15:12:27 | Taint externally controlled string at command_injection.py:12 | +| command_injection.py:17:13:17:24 | Taint {externally controlled string} at command_injection.py:17 | command_injection.py:17:13:17:41 | Taint externally controlled string at command_injection.py:17 | +| command_injection.py:17:13:17:41 | Taint externally controlled string at command_injection.py:17 | command_injection.py:19:29:19:33 | Taint externally controlled string at command_injection.py:19 | +| command_injection.py:19:29:19:33 | Taint externally controlled string at command_injection.py:19 | command_injection.py:19:22:19:34 | Taint [externally controlled string] at command_injection.py:19 | +| command_injection.py:24:11:24:22 | Taint {externally controlled string} at command_injection.py:24 | command_injection.py:24:11:24:37 | Taint externally controlled string at command_injection.py:24 | +| command_injection.py:24:11:24:37 | Taint externally controlled string at command_injection.py:24 | command_injection.py:25:23:25:25 | Taint externally controlled string at command_injection.py:25 | +| command_injection.py:25:23:25:25 | Taint externally controlled string at command_injection.py:25 | command_injection.py:25:22:25:36 | Taint [externally controlled string] at command_injection.py:25 | +| command_injection.py:25:23:25:25 | Taint externally controlled string at command_injection.py:25 | command_injection.py:25:22:25:36 | Taint sequence[externally controlled string][0] at command_injection.py:25 | +parents +| ../lib/os/__init__.py:1:12:1:14 | Taint externally controlled string at ../lib/os/__init__.py:1 | command_injection.py:12:15:12:27 | Taint externally controlled string at command_injection.py:12 | +#select +| command_injection.py:12:15:12:27 | shell command | command_injection.py:10:13:10:24 | Taint {externally controlled string} at command_injection.py:10 | command_injection.py:12:15:12:27 | Taint externally controlled string at command_injection.py:12 | This command depends on $@. | command_injection.py:10:13:10:24 | flask.request.args | a user-provided value | +| command_injection.py:19:22:19:34 | shell command | command_injection.py:17:13:17:24 | Taint {externally controlled string} at command_injection.py:17 | command_injection.py:19:22:19:34 | Taint [externally controlled string] at command_injection.py:19 | This command depends on $@. | command_injection.py:17:13:17:24 | flask.request.args | a user-provided value | +| command_injection.py:25:22:25:36 | OS command first argument | command_injection.py:24:11:24:22 | Taint {externally controlled string} at command_injection.py:24 | command_injection.py:25:22:25:36 | Taint [externally controlled string] at command_injection.py:25 | This command depends on $@. | command_injection.py:24:11:24:22 | flask.request.args | a user-provided value | +| command_injection.py:25:22:25:36 | OS command first argument | command_injection.py:24:11:24:22 | Taint {externally controlled string} at command_injection.py:24 | command_injection.py:25:22:25:36 | Taint sequence[externally controlled string][0] at command_injection.py:25 | This command depends on $@. | command_injection.py:24:11:24:22 | flask.request.args | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected b/python/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected index d9d226b62482..1f1e49293fe9 100644 --- a/python/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected +++ b/python/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected @@ -1 +1,13 @@ -| ../lib/flask/__init__.py:16:25:16:26 | flask.response.argument | Cross-site scripting vulnerability due to $@. | reflected_xss.py:7:18:7:29 | flask.request.args | user-provided value | +edges +| ../lib/flask/__init__.py:14:19:14:20 | Taint externally controlled string at ../lib/flask/__init__.py:14 | ../lib/flask/__init__.py:15:19:15:20 | Taint externally controlled string at ../lib/flask/__init__.py:15 | +| ../lib/flask/__init__.py:14:19:14:20 | Taint externally controlled string at ../lib/flask/__init__.py:14 | ../lib/flask/__init__.py:16:25:16:26 | Taint externally controlled string at ../lib/flask/__init__.py:16 | +| reflected_xss.py:7:18:7:29 | Taint {externally controlled string} at reflected_xss.py:7 | reflected_xss.py:7:18:7:45 | Taint externally controlled string at reflected_xss.py:7 | +| reflected_xss.py:7:18:7:45 | Taint externally controlled string at reflected_xss.py:7 | reflected_xss.py:8:44:8:53 | Taint externally controlled string at reflected_xss.py:8 | +| reflected_xss.py:8:26:8:53 | Taint externally controlled string at reflected_xss.py:8 | ../lib/flask/__init__.py:14:19:14:20 | Taint externally controlled string at ../lib/flask/__init__.py:14 | +| reflected_xss.py:8:44:8:53 | Taint externally controlled string at reflected_xss.py:8 | reflected_xss.py:8:26:8:53 | Taint externally controlled string at reflected_xss.py:8 | +| reflected_xss.py:12:18:12:29 | Taint {externally controlled string} at reflected_xss.py:12 | reflected_xss.py:12:18:12:45 | Taint externally controlled string at reflected_xss.py:12 | +| reflected_xss.py:12:18:12:45 | Taint externally controlled string at reflected_xss.py:12 | reflected_xss.py:13:51:13:60 | Taint externally controlled string at reflected_xss.py:13 | +parents +| ../lib/flask/__init__.py:14:19:14:20 | Taint externally controlled string at ../lib/flask/__init__.py:14 | reflected_xss.py:8:26:8:53 | Taint externally controlled string at reflected_xss.py:8 | +#select +| ../lib/flask/__init__.py:16:25:16:26 | flask.response.argument | reflected_xss.py:7:18:7:29 | Taint {externally controlled string} at reflected_xss.py:7 | ../lib/flask/__init__.py:16:25:16:26 | Taint externally controlled string at ../lib/flask/__init__.py:16 | Cross-site scripting vulnerability due to $@. | reflected_xss.py:7:18:7:29 | flask.request.args | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-089/SqlInjection.expected b/python/ql/test/query-tests/Security/CWE-089/SqlInjection.expected index 01a1f6f0b43f..5144f195f246 100644 --- a/python/ql/test/query-tests/Security/CWE-089/SqlInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-089/SqlInjection.expected @@ -1,4 +1,13 @@ -| sql_injection.py:19:13:19:66 | db.connection.execute | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | Django request source | a user-provided value | -| sql_injection.py:22:38:22:91 | django.db.models.expressions.RawSQL(sink,...) | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | Django request source | a user-provided value | -| sql_injection.py:23:26:23:79 | django.models.QuerySet.raw(sink,...) | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | Django request source | a user-provided value | -| sql_injection.py:24:28:24:81 | django.models.QuerySet.extra(sink,...) | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | Django request source | a user-provided value | +edges +| sql_injection.py:5:15:5:21 | Taint django.request.HttpRequest at sql_injection.py:5 | sql_injection.py:7:8:7:14 | Taint django.request.HttpRequest at sql_injection.py:7 | +| sql_injection.py:5:15:5:21 | Taint django.request.HttpRequest at sql_injection.py:5 | sql_injection.py:8:16:8:22 | Taint django.request.HttpRequest at sql_injection.py:8 | +| sql_injection.py:8:16:8:22 | Taint django.request.HttpRequest at sql_injection.py:8 | sql_injection.py:8:16:8:27 | Taint django.http.request.QueryDict at sql_injection.py:8 | +| sql_injection.py:8:16:8:27 | Taint django.http.request.QueryDict at sql_injection.py:8 | sql_injection.py:8:16:8:39 | Taint externally controlled string at sql_injection.py:8 | +| sql_injection.py:8:16:8:39 | Taint externally controlled string at sql_injection.py:8 | sql_injection.py:12:62:12:65 | Taint externally controlled string at sql_injection.py:12 | +| sql_injection.py:8:16:8:39 | Taint externally controlled string at sql_injection.py:8 | sql_injection.py:15:63:15:66 | Taint externally controlled string at sql_injection.py:15 | +| sql_injection.py:9:16:9:34 | Taint django.db.connection.cursor at sql_injection.py:9 | sql_injection.py:11:9:11:12 | Taint django.db.connection.cursor at sql_injection.py:11 | +| sql_injection.py:9:16:9:34 | Taint django.db.connection.cursor at sql_injection.py:9 | sql_injection.py:14:9:14:12 | Taint django.db.connection.cursor at sql_injection.py:14 | +| sql_injection.py:15:63:15:66 | Taint externally controlled string at sql_injection.py:15 | sql_injection.py:15:13:15:66 | Taint externally controlled string at sql_injection.py:15 | +parents +#select +| sql_injection.py:15:13:15:66 | db.connection.execute | sql_injection.py:5:15:5:21 | Taint django.request.HttpRequest at sql_injection.py:5 | sql_injection.py:15:13:15:66 | Taint externally controlled string at sql_injection.py:15 | This SQL query depends on $@. | sql_injection.py:5:15:5:21 | Django request source | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-094/CodeInjection.expected b/python/ql/test/query-tests/Security/CWE-094/CodeInjection.expected index 02a6bc6255d8..48980e5b6a93 100644 --- a/python/ql/test/query-tests/Security/CWE-094/CodeInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-094/CodeInjection.expected @@ -1 +1,12 @@ -| code_injection.py:7:14:7:44 | exec or eval | $@ flows to here and is interpreted as code. | code_injection.py:4:20:4:26 | Django request source | User-provided value | +edges +| code_injection.py:4:20:4:26 | Taint django.request.HttpRequest at code_injection.py:4 | code_injection.py:5:8:5:14 | Taint django.request.HttpRequest at code_injection.py:5 | +| code_injection.py:4:20:4:26 | Taint django.request.HttpRequest at code_injection.py:4 | code_injection.py:6:22:6:28 | Taint django.request.HttpRequest at code_injection.py:6 | +| code_injection.py:6:22:6:28 | Taint django.request.HttpRequest at code_injection.py:6 | code_injection.py:6:22:6:33 | Taint django.http.request.QueryDict at code_injection.py:6 | +| code_injection.py:6:22:6:33 | Taint django.http.request.QueryDict at code_injection.py:6 | code_injection.py:6:22:6:55 | Taint externally controlled string at code_injection.py:6 | +| code_injection.py:6:22:6:55 | Taint externally controlled string at code_injection.py:6 | code_injection.py:7:34:7:43 | Taint externally controlled string at code_injection.py:7 | +| code_injection.py:7:34:7:43 | Taint externally controlled string at code_injection.py:7 | ../lib/base64.py:1:18:1:18 | Taint externally controlled string at ../lib/base64.py:1 | +| code_injection.py:7:34:7:43 | Taint externally controlled string at code_injection.py:7 | code_injection.py:7:14:7:44 | Taint externally controlled string at code_injection.py:7 | +parents +| ../lib/base64.py:1:18:1:18 | Taint externally controlled string at ../lib/base64.py:1 | code_injection.py:7:34:7:43 | Taint externally controlled string at code_injection.py:7 | +#select +| code_injection.py:7:14:7:44 | exec or eval | code_injection.py:4:20:4:26 | Taint django.request.HttpRequest at code_injection.py:4 | code_injection.py:7:14:7:44 | Taint externally controlled string at code_injection.py:7 | $@ flows to here and is interpreted as code. | code_injection.py:4:20:4:26 | Django request source | User-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected b/python/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected index a0d1a9f8b4e9..522188d9152f 100644 --- a/python/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected +++ b/python/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected @@ -1,3 +1,12 @@ -| test.py:12:18:12:24 | unpickling untrusted data | Deserializing of $@. | test.py:11:15:11:26 | flask.request.args | untrusted input | -| test.py:13:15:13:21 | yaml.load vulnerability | Deserializing of $@. | test.py:11:15:11:26 | flask.request.args | untrusted input | -| test.py:14:19:14:25 | unmarshaling vulnerability | Deserializing of $@. | test.py:11:15:11:26 | flask.request.args | untrusted input | +edges +| test.py:11:15:11:26 | Taint {externally controlled string} at test.py:11 | test.py:11:15:11:41 | Taint externally controlled string at test.py:11 | +| test.py:11:15:11:41 | Taint externally controlled string at test.py:11 | test.py:12:18:12:24 | Taint externally controlled string at test.py:12 | +| test.py:11:15:11:41 | Taint externally controlled string at test.py:11 | test.py:13:15:13:21 | Taint externally controlled string at test.py:13 | +| test.py:11:15:11:41 | Taint externally controlled string at test.py:11 | test.py:14:19:14:25 | Taint externally controlled string at test.py:14 | +| test.py:13:15:13:21 | Taint externally controlled string at test.py:13 | ../lib/yaml.py:1:10:1:10 | Taint externally controlled string at ../lib/yaml.py:1 | +parents +| ../lib/yaml.py:1:10:1:10 | Taint externally controlled string at ../lib/yaml.py:1 | test.py:13:15:13:21 | Taint externally controlled string at test.py:13 | +#select +| test.py:12:18:12:24 | unpickling untrusted data | test.py:11:15:11:26 | Taint {externally controlled string} at test.py:11 | test.py:12:18:12:24 | Taint externally controlled string at test.py:12 | Deserializing of $@. | test.py:11:15:11:26 | flask.request.args | untrusted input | +| test.py:13:15:13:21 | yaml.load vulnerability | test.py:11:15:11:26 | Taint {externally controlled string} at test.py:11 | test.py:13:15:13:21 | Taint externally controlled string at test.py:13 | Deserializing of $@. | test.py:11:15:11:26 | flask.request.args | untrusted input | +| test.py:14:19:14:25 | unmarshaling vulnerability | test.py:11:15:11:26 | Taint {externally controlled string} at test.py:11 | test.py:14:19:14:25 | Taint externally controlled string at test.py:14 | Deserializing of $@. | test.py:11:15:11:26 | flask.request.args | untrusted input | diff --git a/python/ql/test/query-tests/Security/CWE-601/UrlRedirect.expected b/python/ql/test/query-tests/Security/CWE-601/UrlRedirect.expected index a62664e2918c..c4c0df06c12e 100644 --- a/python/ql/test/query-tests/Security/CWE-601/UrlRedirect.expected +++ b/python/ql/test/query-tests/Security/CWE-601/UrlRedirect.expected @@ -1 +1,10 @@ -| test.py:8:21:8:26 | flask.redirect | Untrusted URL redirection due to $@. | test.py:7:22:7:33 | flask.request.args | a user-provided value | +edges +| test.py:7:22:7:33 | Taint {externally controlled string} at test.py:7 | test.py:7:22:7:51 | Taint externally controlled string at test.py:7 | +| test.py:7:22:7:51 | Taint externally controlled string at test.py:7 | test.py:8:21:8:26 | Taint externally controlled string at test.py:8 | +| test.py:8:21:8:26 | Taint externally controlled string at test.py:8 | ../lib/flask/__init__.py:11:14:11:21 | Taint externally controlled string at ../lib/flask/__init__.py:11 | +| test.py:15:17:15:28 | Taint {externally controlled string} at test.py:15 | test.py:15:17:15:42 | Taint externally controlled string at test.py:15 | +| test.py:15:17:15:42 | Taint externally controlled string at test.py:15 | test.py:17:13:17:21 | Taint externally controlled string at test.py:17 | +parents +| ../lib/flask/__init__.py:11:14:11:21 | Taint externally controlled string at ../lib/flask/__init__.py:11 | test.py:8:21:8:26 | Taint externally controlled string at test.py:8 | +#select +| test.py:8:21:8:26 | flask.redirect | test.py:7:22:7:33 | Taint {externally controlled string} at test.py:7 | test.py:8:21:8:26 | Taint externally controlled string at test.py:8 | Untrusted URL redirection due to $@. | test.py:7:22:7:33 | flask.request.args | a user-provided value | diff --git a/semmlecode-python-tests/query-tests/Security/lib/base64.py b/semmlecode-python-tests/query-tests/Security/lib/base64.py new file mode 100644 index 000000000000..a2b97ca63acc --- /dev/null +++ b/semmlecode-python-tests/query-tests/Security/lib/base64.py @@ -0,0 +1,2 @@ +def decodestring(s): + return None diff --git a/semmlecode-python-tests/query-tests/Security/lib/marshall.py b/semmlecode-python-tests/query-tests/Security/lib/marshall.py new file mode 100644 index 000000000000..410fa21087e5 --- /dev/null +++ b/semmlecode-python-tests/query-tests/Security/lib/marshall.py @@ -0,0 +1,2 @@ +def loads(*args, **kwargs): + return None diff --git a/semmlecode-python-tests/query-tests/Security/lib/os/__init__.py b/semmlecode-python-tests/query-tests/Security/lib/os/__init__.py new file mode 100644 index 000000000000..84286e873b58 --- /dev/null +++ b/semmlecode-python-tests/query-tests/Security/lib/os/__init__.py @@ -0,0 +1,2 @@ +def system(cmd, *args, **kwargs): + return None \ No newline at end of file diff --git a/semmlecode-python-tests/query-tests/Security/lib/os/path.py b/semmlecode-python-tests/query-tests/Security/lib/os/path.py new file mode 100644 index 000000000000..77e40f071649 --- /dev/null +++ b/semmlecode-python-tests/query-tests/Security/lib/os/path.py @@ -0,0 +1,5 @@ +def join(a, b): + return a + "/" + b + +def normpath(x): + return x diff --git a/semmlecode-python-tests/query-tests/Security/lib/pickle.py b/semmlecode-python-tests/query-tests/Security/lib/pickle.py new file mode 100644 index 000000000000..410fa21087e5 --- /dev/null +++ b/semmlecode-python-tests/query-tests/Security/lib/pickle.py @@ -0,0 +1,2 @@ +def loads(*args, **kwargs): + return None diff --git a/semmlecode-python-tests/query-tests/Security/lib/subprocess.py b/semmlecode-python-tests/query-tests/Security/lib/subprocess.py new file mode 100644 index 000000000000..efb2ba183f09 --- /dev/null +++ b/semmlecode-python-tests/query-tests/Security/lib/subprocess.py @@ -0,0 +1,2 @@ +def Popen(*args, **kwargs): + return None \ No newline at end of file diff --git a/semmlecode-python-tests/query-tests/Security/lib/traceback.py b/semmlecode-python-tests/query-tests/Security/lib/traceback.py new file mode 100644 index 000000000000..2a7c5e58847a --- /dev/null +++ b/semmlecode-python-tests/query-tests/Security/lib/traceback.py @@ -0,0 +1,2 @@ +def format_exc(): + return None \ No newline at end of file From 88d82017b38b1d4ed7e363554dc3c3c2fc328d20 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 16 Nov 2018 14:39:48 +0000 Subject: [PATCH 3/8] Python: Convert stack-trace-exposure query to path-problem. --- .../Security/CWE-209/StackTraceExposure.expected | 12 +++++++++++- python/ql/test/query-tests/Security/CWE-209/test.py | 12 ++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/python/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected b/python/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected index 7c16a2d95f81..c5d0f64988e5 100644 --- a/python/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected +++ b/python/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected @@ -1 +1,11 @@ -| test.py:16:16:16:37 | flask.routed.response | $@ may be exposed to an external user | test.py:16:16:16:37 | exception.info.source | Error information | +edges +| test.py:33:15:33:36 | Taint exception.info at test.py:33 | test.py:34:29:34:31 | Taint exception.info at test.py:34 | +| test.py:34:29:34:31 | Taint exception.info at test.py:34 | test.py:36:18:36:20 | Taint exception.info at test.py:36 | +| test.py:36:18:36:20 | Taint exception.info at test.py:36 | test.py:37:25:37:27 | Taint exception.info at test.py:37 | +| test.py:37:12:37:27 | Taint exception.info at test.py:37 | test.py:34:16:34:32 | Taint exception.info at test.py:34 | +| test.py:37:25:37:27 | Taint exception.info at test.py:37 | test.py:37:12:37:27 | Taint exception.info at test.py:37 | +parents +| test.py:36:18:36:20 | Taint exception.info at test.py:36 | test.py:34:29:34:31 | Taint exception.info at test.py:34 | +#select +| test.py:16:16:16:37 | flask.routed.response | test.py:16:16:16:37 | Taint exception.info at test.py:16 | test.py:16:16:16:37 | Taint exception.info at test.py:16 | $@ may be exposed to an external user | test.py:16:16:16:37 | exception.info.source | Error information | +| test.py:34:16:34:32 | flask.routed.response | test.py:33:15:33:36 | Taint exception.info at test.py:33 | test.py:34:16:34:32 | Taint exception.info at test.py:34 | $@ may be exposed to an external user | test.py:33:15:33:36 | exception.info.source | Error information | diff --git a/python/ql/test/query-tests/Security/CWE-209/test.py b/python/ql/test/query-tests/Security/CWE-209/test.py index 169dc091dddd..6e96cba15c57 100644 --- a/python/ql/test/query-tests/Security/CWE-209/test.py +++ b/python/ql/test/query-tests/Security/CWE-209/test.py @@ -23,3 +23,15 @@ def server_good(): except Exception as e: log(traceback.format_exc()) return "An internal error has occurred!" + +#BAD +@app.route('/bad/with-flow') +def server_bad_flow(): + try: + do_computation() + except Exception as e: + err = traceback.format_exc() + return format_error(err) + +def format_error(msg): + return "[ERROR] " + msg From 04e5b8927a9e3820586587f74dae2940dede02a8 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 16 Nov 2018 16:05:12 +0000 Subject: [PATCH 4/8] Python tests: use a more accurate form os os.path.join() in test lib. --- .../Security/CWE-022/PathInjection.expected | 20 ------------------- .../query-tests/Security/lib/os/path.py | 4 ++-- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/python/ql/test/query-tests/Security/CWE-022/PathInjection.expected b/python/ql/test/query-tests/Security/CWE-022/PathInjection.expected index d6791fde69bd..73eb7a46fe0f 100644 --- a/python/ql/test/query-tests/Security/CWE-022/PathInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-022/PathInjection.expected @@ -1,29 +1,15 @@ edges -| ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | ../lib/os/path.py:2:22:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | -| ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | ../lib/os/path.py:2:22:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | -| ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | ../lib/os/path.py:2:22:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | -| ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | ../lib/os/path.py:2:22:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | -| ../lib/os/path.py:2:12:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | path_injection.py:10:14:10:44 | Taint externally controlled string at path_injection.py:10 | -| ../lib/os/path.py:2:12:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | path_injection.py:16:30:16:60 | Taint externally controlled string at path_injection.py:16 | -| ../lib/os/path.py:2:12:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | path_injection.py:25:30:25:60 | Taint externally controlled string at path_injection.py:25 | -| ../lib/os/path.py:2:12:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | path_injection.py:34:30:34:60 | Taint externally controlled string at path_injection.py:34 | -| ../lib/os/path.py:2:22:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | ../lib/os/path.py:2:12:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | -| ../lib/os/path.py:2:22:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | ../lib/os/path.py:2:12:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | -| ../lib/os/path.py:2:22:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | ../lib/os/path.py:2:12:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | -| ../lib/os/path.py:2:22:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | ../lib/os/path.py:2:12:2:22 | Taint externally controlled string at ../lib/os/path.py:2 | | ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | ../lib/os/path.py:5:12:5:12 | Taint externally controlled string at ../lib/os/path.py:5 | | ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | ../lib/os/path.py:5:12:5:12 | Taint externally controlled string at ../lib/os/path.py:5 | | ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | ../lib/os/path.py:5:12:5:12 | Taint externally controlled string at ../lib/os/path.py:5 | | path_injection.py:9:12:9:23 | Taint {externally controlled string} at path_injection.py:9 | path_injection.py:9:12:9:39 | Taint externally controlled string at path_injection.py:9 | | path_injection.py:9:12:9:39 | Taint externally controlled string at path_injection.py:9 | path_injection.py:10:40:10:43 | Taint externally controlled string at path_injection.py:10 | -| path_injection.py:10:40:10:43 | Taint externally controlled string at path_injection.py:10 | ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | | path_injection.py:10:40:10:43 | Taint externally controlled string at path_injection.py:10 | path_injection.py:10:14:10:44 | Taint externally controlled string at path_injection.py:10 | | path_injection.py:15:12:15:23 | Taint {externally controlled string} at path_injection.py:15 | path_injection.py:15:12:15:39 | Taint externally controlled string at path_injection.py:15 | | path_injection.py:15:12:15:39 | Taint externally controlled string at path_injection.py:15 | path_injection.py:16:56:16:59 | Taint externally controlled string at path_injection.py:16 | | path_injection.py:16:13:16:61 | Taint normalized.path.injection at path_injection.py:16 | path_injection.py:17:14:17:18 | Taint normalized.path.injection at path_injection.py:17 | | path_injection.py:16:30:16:60 | Taint externally controlled string at path_injection.py:16 | ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | | path_injection.py:16:30:16:60 | Taint externally controlled string at path_injection.py:16 | path_injection.py:16:13:16:61 | Taint normalized.path.injection at path_injection.py:16 | -| path_injection.py:16:56:16:59 | Taint externally controlled string at path_injection.py:16 | ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | | path_injection.py:16:56:16:59 | Taint externally controlled string at path_injection.py:16 | path_injection.py:16:30:16:60 | Taint externally controlled string at path_injection.py:16 | | path_injection.py:24:12:24:23 | Taint {externally controlled string} at path_injection.py:24 | path_injection.py:24:12:24:39 | Taint externally controlled string at path_injection.py:24 | | path_injection.py:24:12:24:39 | Taint externally controlled string at path_injection.py:24 | path_injection.py:25:56:25:59 | Taint externally controlled string at path_injection.py:25 | @@ -31,20 +17,14 @@ edges | path_injection.py:25:13:25:61 | Taint normalized.path.injection at path_injection.py:25 | path_injection.py:28:14:28:18 | Taint normalized.path.injection at path_injection.py:28 | | path_injection.py:25:30:25:60 | Taint externally controlled string at path_injection.py:25 | ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | | path_injection.py:25:30:25:60 | Taint externally controlled string at path_injection.py:25 | path_injection.py:25:13:25:61 | Taint normalized.path.injection at path_injection.py:25 | -| path_injection.py:25:56:25:59 | Taint externally controlled string at path_injection.py:25 | ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | | path_injection.py:25:56:25:59 | Taint externally controlled string at path_injection.py:25 | path_injection.py:25:30:25:60 | Taint externally controlled string at path_injection.py:25 | | path_injection.py:33:12:33:23 | Taint {externally controlled string} at path_injection.py:33 | path_injection.py:33:12:33:39 | Taint externally controlled string at path_injection.py:33 | | path_injection.py:33:12:33:39 | Taint externally controlled string at path_injection.py:33 | path_injection.py:34:56:34:59 | Taint externally controlled string at path_injection.py:34 | | path_injection.py:34:13:34:61 | Taint normalized.path.injection at path_injection.py:34 | path_injection.py:35:8:35:12 | Taint normalized.path.injection at path_injection.py:35 | | path_injection.py:34:30:34:60 | Taint externally controlled string at path_injection.py:34 | ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | | path_injection.py:34:30:34:60 | Taint externally controlled string at path_injection.py:34 | path_injection.py:34:13:34:61 | Taint normalized.path.injection at path_injection.py:34 | -| path_injection.py:34:56:34:59 | Taint externally controlled string at path_injection.py:34 | ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | | path_injection.py:34:56:34:59 | Taint externally controlled string at path_injection.py:34 | path_injection.py:34:30:34:60 | Taint externally controlled string at path_injection.py:34 | parents -| ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | path_injection.py:10:40:10:43 | Taint externally controlled string at path_injection.py:10 | -| ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | path_injection.py:16:56:16:59 | Taint externally controlled string at path_injection.py:16 | -| ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | path_injection.py:25:56:25:59 | Taint externally controlled string at path_injection.py:25 | -| ../lib/os/path.py:1:13:1:13 | Taint externally controlled string at ../lib/os/path.py:1 | path_injection.py:34:56:34:59 | Taint externally controlled string at path_injection.py:34 | | ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | path_injection.py:16:30:16:60 | Taint externally controlled string at path_injection.py:16 | | ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | path_injection.py:25:30:25:60 | Taint externally controlled string at path_injection.py:25 | | ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | path_injection.py:34:30:34:60 | Taint externally controlled string at path_injection.py:34 | diff --git a/semmlecode-python-tests/query-tests/Security/lib/os/path.py b/semmlecode-python-tests/query-tests/Security/lib/os/path.py index 77e40f071649..d54092e80b0d 100644 --- a/semmlecode-python-tests/query-tests/Security/lib/os/path.py +++ b/semmlecode-python-tests/query-tests/Security/lib/os/path.py @@ -1,5 +1,5 @@ -def join(a, b): - return a + "/" + b +def join(a, *b): + return a + "/" + "/".join(b) def normpath(x): return x From f3fedcdf38315243ae77b43b23e978ef3f47ece2 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 21 Nov 2018 15:22:46 +0000 Subject: [PATCH 5/8] Python tests: Move security test stubs to correct location. --- .../ql/test}/query-tests/Security/lib/base64.py | 0 .../ql/test}/query-tests/Security/lib/marshall.py | 0 .../ql/test}/query-tests/Security/lib/os/__init__.py | 0 .../ql/test}/query-tests/Security/lib/os/path.py | 0 .../ql/test}/query-tests/Security/lib/pickle.py | 0 .../ql/test}/query-tests/Security/lib/subprocess.py | 0 .../ql/test}/query-tests/Security/lib/traceback.py | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename {semmlecode-python-tests => python/ql/test}/query-tests/Security/lib/base64.py (100%) rename {semmlecode-python-tests => python/ql/test}/query-tests/Security/lib/marshall.py (100%) rename {semmlecode-python-tests => python/ql/test}/query-tests/Security/lib/os/__init__.py (100%) rename {semmlecode-python-tests => python/ql/test}/query-tests/Security/lib/os/path.py (100%) rename {semmlecode-python-tests => python/ql/test}/query-tests/Security/lib/pickle.py (100%) rename {semmlecode-python-tests => python/ql/test}/query-tests/Security/lib/subprocess.py (100%) rename {semmlecode-python-tests => python/ql/test}/query-tests/Security/lib/traceback.py (100%) diff --git a/semmlecode-python-tests/query-tests/Security/lib/base64.py b/python/ql/test/query-tests/Security/lib/base64.py similarity index 100% rename from semmlecode-python-tests/query-tests/Security/lib/base64.py rename to python/ql/test/query-tests/Security/lib/base64.py diff --git a/semmlecode-python-tests/query-tests/Security/lib/marshall.py b/python/ql/test/query-tests/Security/lib/marshall.py similarity index 100% rename from semmlecode-python-tests/query-tests/Security/lib/marshall.py rename to python/ql/test/query-tests/Security/lib/marshall.py diff --git a/semmlecode-python-tests/query-tests/Security/lib/os/__init__.py b/python/ql/test/query-tests/Security/lib/os/__init__.py similarity index 100% rename from semmlecode-python-tests/query-tests/Security/lib/os/__init__.py rename to python/ql/test/query-tests/Security/lib/os/__init__.py diff --git a/semmlecode-python-tests/query-tests/Security/lib/os/path.py b/python/ql/test/query-tests/Security/lib/os/path.py similarity index 100% rename from semmlecode-python-tests/query-tests/Security/lib/os/path.py rename to python/ql/test/query-tests/Security/lib/os/path.py diff --git a/semmlecode-python-tests/query-tests/Security/lib/pickle.py b/python/ql/test/query-tests/Security/lib/pickle.py similarity index 100% rename from semmlecode-python-tests/query-tests/Security/lib/pickle.py rename to python/ql/test/query-tests/Security/lib/pickle.py diff --git a/semmlecode-python-tests/query-tests/Security/lib/subprocess.py b/python/ql/test/query-tests/Security/lib/subprocess.py similarity index 100% rename from semmlecode-python-tests/query-tests/Security/lib/subprocess.py rename to python/ql/test/query-tests/Security/lib/subprocess.py diff --git a/semmlecode-python-tests/query-tests/Security/lib/traceback.py b/python/ql/test/query-tests/Security/lib/traceback.py similarity index 100% rename from semmlecode-python-tests/query-tests/Security/lib/traceback.py rename to python/ql/test/query-tests/Security/lib/traceback.py From bfb7e17ebf59f2f96a9b06a3c5868ed5e73d9df4 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 21 Nov 2018 17:26:33 +0000 Subject: [PATCH 6/8] Python: Move library to correct location. --- .../ql/src}/semmle/python/security/Paths.qll | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {semmlecode-python-queries => python/ql/src}/semmle/python/security/Paths.qll (100%) diff --git a/semmlecode-python-queries/semmle/python/security/Paths.qll b/python/ql/src/semmle/python/security/Paths.qll similarity index 100% rename from semmlecode-python-queries/semmle/python/security/Paths.qll rename to python/ql/src/semmle/python/security/Paths.qll From c01db23f587a2b0adb7a8da109a7ccaa9b31bf2d Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 21 Nov 2018 17:45:40 +0000 Subject: [PATCH 7/8] Python: Fix up expected results of SqlInjection.ql --- .../Security/CWE-089/SqlInjection.expected | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/python/ql/test/query-tests/Security/CWE-089/SqlInjection.expected b/python/ql/test/query-tests/Security/CWE-089/SqlInjection.expected index 5144f195f246..33d87c296d6e 100644 --- a/python/ql/test/query-tests/Security/CWE-089/SqlInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-089/SqlInjection.expected @@ -1,13 +1,25 @@ edges -| sql_injection.py:5:15:5:21 | Taint django.request.HttpRequest at sql_injection.py:5 | sql_injection.py:7:8:7:14 | Taint django.request.HttpRequest at sql_injection.py:7 | -| sql_injection.py:5:15:5:21 | Taint django.request.HttpRequest at sql_injection.py:5 | sql_injection.py:8:16:8:22 | Taint django.request.HttpRequest at sql_injection.py:8 | -| sql_injection.py:8:16:8:22 | Taint django.request.HttpRequest at sql_injection.py:8 | sql_injection.py:8:16:8:27 | Taint django.http.request.QueryDict at sql_injection.py:8 | -| sql_injection.py:8:16:8:27 | Taint django.http.request.QueryDict at sql_injection.py:8 | sql_injection.py:8:16:8:39 | Taint externally controlled string at sql_injection.py:8 | -| sql_injection.py:8:16:8:39 | Taint externally controlled string at sql_injection.py:8 | sql_injection.py:12:62:12:65 | Taint externally controlled string at sql_injection.py:12 | -| sql_injection.py:8:16:8:39 | Taint externally controlled string at sql_injection.py:8 | sql_injection.py:15:63:15:66 | Taint externally controlled string at sql_injection.py:15 | -| sql_injection.py:9:16:9:34 | Taint django.db.connection.cursor at sql_injection.py:9 | sql_injection.py:11:9:11:12 | Taint django.db.connection.cursor at sql_injection.py:11 | -| sql_injection.py:9:16:9:34 | Taint django.db.connection.cursor at sql_injection.py:9 | sql_injection.py:14:9:14:12 | Taint django.db.connection.cursor at sql_injection.py:14 | -| sql_injection.py:15:63:15:66 | Taint externally controlled string at sql_injection.py:15 | sql_injection.py:15:13:15:66 | Taint externally controlled string at sql_injection.py:15 | +| sql_injection.py:9:15:9:21 | Taint django.request.HttpRequest at sql_injection.py:9 | sql_injection.py:11:8:11:14 | Taint django.request.HttpRequest at sql_injection.py:11 | +| sql_injection.py:9:15:9:21 | Taint django.request.HttpRequest at sql_injection.py:9 | sql_injection.py:12:16:12:22 | Taint django.request.HttpRequest at sql_injection.py:12 | +| sql_injection.py:12:16:12:22 | Taint django.request.HttpRequest at sql_injection.py:12 | sql_injection.py:12:16:12:27 | Taint django.http.request.QueryDict at sql_injection.py:12 | +| sql_injection.py:12:16:12:27 | Taint django.http.request.QueryDict at sql_injection.py:12 | sql_injection.py:12:16:12:39 | Taint externally controlled string at sql_injection.py:12 | +| sql_injection.py:12:16:12:39 | Taint externally controlled string at sql_injection.py:12 | sql_injection.py:16:62:16:65 | Taint externally controlled string at sql_injection.py:16 | +| sql_injection.py:12:16:12:39 | Taint externally controlled string at sql_injection.py:12 | sql_injection.py:19:63:19:66 | Taint externally controlled string at sql_injection.py:19 | +| sql_injection.py:12:16:12:39 | Taint externally controlled string at sql_injection.py:12 | sql_injection.py:22:88:22:91 | Taint externally controlled string at sql_injection.py:22 | +| sql_injection.py:12:16:12:39 | Taint externally controlled string at sql_injection.py:12 | sql_injection.py:23:76:23:79 | Taint externally controlled string at sql_injection.py:23 | +| sql_injection.py:12:16:12:39 | Taint externally controlled string at sql_injection.py:12 | sql_injection.py:24:78:24:81 | Taint externally controlled string at sql_injection.py:24 | +| sql_injection.py:13:16:13:34 | Taint django.db.connection.cursor at sql_injection.py:13 | sql_injection.py:15:9:15:12 | Taint django.db.connection.cursor at sql_injection.py:15 | +| sql_injection.py:13:16:13:34 | Taint django.db.connection.cursor at sql_injection.py:13 | sql_injection.py:18:9:18:12 | Taint django.db.connection.cursor at sql_injection.py:18 | +| sql_injection.py:19:63:19:66 | Taint externally controlled string at sql_injection.py:19 | sql_injection.py:19:13:19:66 | Taint externally controlled string at sql_injection.py:19 | +| sql_injection.py:22:9:22:20 | Taint django.db.models.Model.objects at sql_injection.py:22 | sql_injection.py:22:9:22:93 | Taint django.db.models.Model.objects at sql_injection.py:22 | +| sql_injection.py:22:88:22:91 | Taint externally controlled string at sql_injection.py:22 | sql_injection.py:22:38:22:91 | Taint externally controlled string at sql_injection.py:22 | +| sql_injection.py:23:9:23:20 | Taint django.db.models.Model.objects at sql_injection.py:23 | sql_injection.py:23:9:23:80 | Taint django.db.models.Model.objects at sql_injection.py:23 | +| sql_injection.py:23:76:23:79 | Taint externally controlled string at sql_injection.py:23 | sql_injection.py:23:26:23:79 | Taint externally controlled string at sql_injection.py:23 | +| sql_injection.py:24:9:24:20 | Taint django.db.models.Model.objects at sql_injection.py:24 | sql_injection.py:24:9:24:82 | Taint django.db.models.Model.objects at sql_injection.py:24 | +| sql_injection.py:24:78:24:81 | Taint externally controlled string at sql_injection.py:24 | sql_injection.py:24:28:24:81 | Taint externally controlled string at sql_injection.py:24 | parents #select -| sql_injection.py:15:13:15:66 | db.connection.execute | sql_injection.py:5:15:5:21 | Taint django.request.HttpRequest at sql_injection.py:5 | sql_injection.py:15:13:15:66 | Taint externally controlled string at sql_injection.py:15 | This SQL query depends on $@. | sql_injection.py:5:15:5:21 | Django request source | a user-provided value | +| sql_injection.py:19:13:19:66 | db.connection.execute | sql_injection.py:9:15:9:21 | Taint django.request.HttpRequest at sql_injection.py:9 | sql_injection.py:19:13:19:66 | Taint externally controlled string at sql_injection.py:19 | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | Django request source | a user-provided value | +| sql_injection.py:22:38:22:91 | django.db.models.expressions.RawSQL(sink,...) | sql_injection.py:9:15:9:21 | Taint django.request.HttpRequest at sql_injection.py:9 | sql_injection.py:22:38:22:91 | Taint externally controlled string at sql_injection.py:22 | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | Django request source | a user-provided value | +| sql_injection.py:23:26:23:79 | django.models.QuerySet.raw(sink,...) | sql_injection.py:9:15:9:21 | Taint django.request.HttpRequest at sql_injection.py:9 | sql_injection.py:23:26:23:79 | Taint externally controlled string at sql_injection.py:23 | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | Django request source | a user-provided value | +| sql_injection.py:24:28:24:81 | django.models.QuerySet.extra(sink,...) | sql_injection.py:9:15:9:21 | Taint django.request.HttpRequest at sql_injection.py:9 | sql_injection.py:24:28:24:81 | Taint externally controlled string at sql_injection.py:24 | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | Django request source | a user-provided value | From 61bd8682dfc8092940eddedfc8a11b7fd7e91c73 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 23 Nov 2018 12:18:56 +0000 Subject: [PATCH 8/8] Python: Improve API and representation of taint tracking nodes. Update queries and tests accordingly. --- .../ql/src/Security/CWE-022/PathInjection.ql | 8 +-- .../src/Security/CWE-078/CommandInjection.ql | 7 +-- .../ql/src/Security/CWE-079/ReflectedXss.ql | 9 +-- .../ql/src/Security/CWE-089/SqlInjection.ql | 7 +-- .../ql/src/Security/CWE-094/CodeInjection.ql | 7 +-- .../Security/CWE-209/StackTraceExposure.ql | 6 +- .../Security/CWE-502/UnsafeDeserialization.ql | 7 +-- python/ql/src/Security/CWE-601/UrlRedirect.ql | 7 +-- .../src/semmle/python/security/Exceptions.qll | 9 +++ .../semmle/python/security/TaintTracking.qll | 45 ++++++++++++-- .../python/security/injection/Command.qll | 3 + .../semmle/python/security/injection/Path.qll | 4 ++ .../Security/CWE-022/PathInjection.expected | 62 +++++++++---------- .../CWE-078/CommandInjection.expected | 31 +++++----- .../Security/CWE-079/ReflectedXss.expected | 20 +++--- .../Security/CWE-089/SqlInjection.expected | 44 ++++++------- .../Security/CWE-094/CodeInjection.expected | 18 +++--- .../CWE-209/StackTraceExposure.expected | 16 ++--- .../CWE-502/UnsafeDeserialization.expected | 18 +++--- .../Security/CWE-601/UrlRedirect.expected | 14 ++--- 20 files changed, 190 insertions(+), 152 deletions(-) diff --git a/python/ql/src/Security/CWE-022/PathInjection.ql b/python/ql/src/Security/CWE-022/PathInjection.ql index 0d54ffc7ff1c..1b1eb33a5073 100644 --- a/python/ql/src/Security/CWE-022/PathInjection.ql +++ b/python/ql/src/Security/CWE-022/PathInjection.ql @@ -26,8 +26,6 @@ import semmle.python.web.HttpRequest import semmle.python.security.injection.Path - -from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink -where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink - -select sink, srcnode, sinknode, "This path depends on $@.", src, "a user-provided value" +from TaintedPathSource src, TaintedPathSink sink +where src.flowsTo(sink) +select sink.getSink(), src, sink, "This path depends on $@.", src.getSource(), "a user-provided value" \ No newline at end of file diff --git a/python/ql/src/Security/CWE-078/CommandInjection.ql b/python/ql/src/Security/CWE-078/CommandInjection.ql index 260f1a8c2440..639aab3725fe 100755 --- a/python/ql/src/Security/CWE-078/CommandInjection.ql +++ b/python/ql/src/Security/CWE-078/CommandInjection.ql @@ -23,7 +23,6 @@ import semmle.python.web.HttpRequest /* Sinks */ import semmle.python.security.injection.Command -from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink -where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink - -select sink, srcnode, sinknode, "This command depends on $@.", src, "a user-provided value" +from TaintedPathSource src, TaintedPathSink sink +where src.flowsTo(sink) +select sink.getSink(), src, sink, "This command depends on $@.", src.getSource(), "a user-provided value" diff --git a/python/ql/src/Security/CWE-079/ReflectedXss.ql b/python/ql/src/Security/CWE-079/ReflectedXss.ql index 28a59b71d418..3a77e0559f63 100644 --- a/python/ql/src/Security/CWE-079/ReflectedXss.ql +++ b/python/ql/src/Security/CWE-079/ReflectedXss.ql @@ -25,9 +25,6 @@ import semmle.python.web.HttpResponse /* Flow */ import semmle.python.security.strings.Untrusted -from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink -where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink - -select sink, srcnode, sinknode, "Cross-site scripting vulnerability due to $@.", - src, "user-provided value" - +from TaintedPathSource src, TaintedPathSink sink +where src.flowsTo(sink) +select sink.getSink(), src, sink, "Cross-site scripting vulnerability due to $@.", src.getSource(), "user-provided value" diff --git a/python/ql/src/Security/CWE-089/SqlInjection.ql b/python/ql/src/Security/CWE-089/SqlInjection.ql index 9189417ad475..35274729418d 100755 --- a/python/ql/src/Security/CWE-089/SqlInjection.ql +++ b/python/ql/src/Security/CWE-089/SqlInjection.ql @@ -23,7 +23,6 @@ import semmle.python.web.django.Db import semmle.python.web.django.Model -from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink -where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink - -select sink, srcnode, sinknode, "This SQL query depends on $@.", src, "a user-provided value" +from TaintedPathSource src, TaintedPathSink sink +where src.flowsTo(sink) +select sink.getSink(), src, sink, "This SQL query depends on $@.", src.getSource(), "a user-provided value" diff --git a/python/ql/src/Security/CWE-094/CodeInjection.ql b/python/ql/src/Security/CWE-094/CodeInjection.ql index e0d5acaba3e8..2d511a5dae41 100644 --- a/python/ql/src/Security/CWE-094/CodeInjection.ql +++ b/python/ql/src/Security/CWE-094/CodeInjection.ql @@ -24,7 +24,6 @@ import semmle.python.web.HttpRequest import semmle.python.security.injection.Exec -from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink -where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink - -select sink, srcnode, sinknode, "$@ flows to here and is interpreted as code.", src, "User-provided value" +from TaintedPathSource src, TaintedPathSink sink +where src.flowsTo(sink) +select sink.getSink(), src, sink, "$@ flows to here and is interpreted as code.", src.getSource(), "User-provided value" diff --git a/python/ql/src/Security/CWE-209/StackTraceExposure.ql b/python/ql/src/Security/CWE-209/StackTraceExposure.ql index c22a744b7b64..4a1452655ed9 100644 --- a/python/ql/src/Security/CWE-209/StackTraceExposure.ql +++ b/python/ql/src/Security/CWE-209/StackTraceExposure.ql @@ -18,6 +18,6 @@ import semmle.python.security.Paths import semmle.python.security.Exceptions import semmle.python.web.HttpResponse -from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink -where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink -select sink, srcnode, sinknode, "$@ may be exposed to an external user", src, "Error information" +from TaintedPathSource src, TaintedPathSink sink +where src.flowsTo(sink) +select sink.getSink(), src, sink, "$@ may be exposed to an external user", src.getSource(), "Error information" diff --git a/python/ql/src/Security/CWE-502/UnsafeDeserialization.ql b/python/ql/src/Security/CWE-502/UnsafeDeserialization.ql index 32ce6fa8361c..fa48c63db9d8 100644 --- a/python/ql/src/Security/CWE-502/UnsafeDeserialization.ql +++ b/python/ql/src/Security/CWE-502/UnsafeDeserialization.ql @@ -25,7 +25,6 @@ import semmle.python.security.injection.Marshal import semmle.python.security.injection.Yaml -from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink -where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink - -select sink, srcnode, sinknode, "Deserializing of $@.", src, "untrusted input" +from TaintedPathSource src, TaintedPathSink sink +where src.flowsTo(sink) +select sink.getSink(), src, sink, "Deserializing of $@.", src.getSource(), "untrusted input" diff --git a/python/ql/src/Security/CWE-601/UrlRedirect.ql b/python/ql/src/Security/CWE-601/UrlRedirect.ql index 9ff1723aab11..4734c540bc38 100644 --- a/python/ql/src/Security/CWE-601/UrlRedirect.ql +++ b/python/ql/src/Security/CWE-601/UrlRedirect.ql @@ -28,8 +28,7 @@ class UntrustedPrefixStringKind extends UntrustedStringKind { } -from TaintedNode srcnode, TaintedNode sinknode, TaintSource src, TaintSink sink -where src.flowsToSink(sink) and srcnode.getNode() = src and sinknode.getNode() = sink - -select sink, srcnode, sinknode, "Untrusted URL redirection due to $@.", src, "a user-provided value" +from TaintedPathSource src, TaintedPathSink sink +where src.flowsTo(sink) +select sink.getSink(), src, sink, "Untrusted URL redirection due to $@.", src.getSource(), "a user-provided value" diff --git a/python/ql/src/semmle/python/security/Exceptions.qll b/python/ql/src/semmle/python/security/Exceptions.qll index a321c9df839d..d0ecee350d58 100644 --- a/python/ql/src/semmle/python/security/Exceptions.qll +++ b/python/ql/src/semmle/python/security/Exceptions.qll @@ -24,6 +24,11 @@ class ExceptionInfo extends StringKind { ExceptionInfo() { this = "exception.info" } + + override string repr() { + result = "exception info" + } + } @@ -36,6 +41,10 @@ class ExceptionKind extends TaintKind { this = "exception.kind" } + override string repr() { + result = "exception" + } + override TaintKind getTaintOfAttribute(string name) { name = "args" and result instanceof ExceptionInfoSequence or diff --git a/python/ql/src/semmle/python/security/TaintTracking.qll b/python/ql/src/semmle/python/security/TaintTracking.qll index d8dd0ea143f9..928806d7f822 100755 --- a/python/ql/src/semmle/python/security/TaintTracking.qll +++ b/python/ql/src/semmle/python/security/TaintTracking.qll @@ -148,6 +148,8 @@ abstract class TaintKind extends string { none() } + string repr() { result = this } + } /** Taint kinds representing collections of other taint kind. @@ -208,6 +210,10 @@ class SequenceKind extends CollectionKind { name = "pop" and result = this.getItem() } + override string repr() { + result = "sequence of " + itemKind + } + } /* Helper for getTaintForStep() */ @@ -281,6 +287,10 @@ class DictKind extends CollectionKind { name = "itervalues" and result.(SequenceKind).getItem() = valueKind } + override string repr() { + result = "dict of " + valueKind + } + } @@ -603,7 +613,9 @@ private predicate user_tainted_def(TaintedDefinition def, TaintFlowImplementatio */ class TaintedNode extends TTaintedNode { - string toString() { result = this.getTrackedValue().toString() + " at " + this.getLocation() } + string toString() { result = this.getTrackedValue().repr() } + + string debug() { result = this.getTrackedValue().toString() + " at " + this.getNode().getLocation() } TaintedNode getASuccessor() { exists(TaintFlowImplementation::TrackedValue tokind, CallContext tocontext, ControlFlowNode tonode | @@ -675,25 +687,33 @@ class TaintedNode extends TTaintedNode { } -class TaintedNodeSource extends TaintedNode { +class TaintedPathSource extends TaintedNode { - TaintedNodeSource() { + TaintedPathSource() { this.getNode().(TaintSource).isSourceOf(this.getTaintKind(), this.getContext()) } /** Holds if taint can flow from this source to sink `sink` */ - final predicate flowsTo(TaintedNodeSink sink) { + final predicate flowsTo(TaintedPathSink sink) { this.getASuccessor*() = sink } + TaintSource getSource() { + result = this.getNode() + } + } -class TaintedNodeSink extends TaintedNode { +class TaintedPathSink extends TaintedNode { - TaintedNodeSink() { + TaintedPathSink() { this.getNode().(TaintSink).sinks(this.getTaintKind()) } + TaintSink getSink() { + result = this.getNode() + } + } /** This module contains the implementation of taint-flow. @@ -739,12 +759,18 @@ library module TaintFlowImplementation { abstract string toString(); + abstract string repr(); + abstract TrackedValue toKind(TaintKind kind); } class TrackedTaint extends TrackedValue, TTrackedTaint { + override string repr() { + result = this.getKind().repr() + } + override string toString() { result = "Taint " + this.getKind() } @@ -761,6 +787,13 @@ library module TaintFlowImplementation { class TrackedAttribute extends TrackedValue, TTrackedAttribute { + override string repr() { + exists(string name, TaintKind kind | + this = TTrackedAttribute(name, kind) and + result = "." + name + "=" + kind.repr() + ) + } + override string toString() { exists(string name, TaintKind kind | this = TTrackedAttribute(name, kind) and diff --git a/python/ql/src/semmle/python/security/injection/Command.qll b/python/ql/src/semmle/python/security/injection/Command.qll index 11ff52a053a1..7bfdb987bfbe 100644 --- a/python/ql/src/semmle/python/security/injection/Command.qll +++ b/python/ql/src/semmle/python/security/injection/Command.qll @@ -36,6 +36,9 @@ class FirstElementKind extends TaintKind { this = "sequence[" + any(ExternalStringKind key) + "][0]" } + override string repr() { + result = "first item in sequence of " + this.getItem().repr() + } /** Gets the taint kind for item in this sequence. */ ExternalStringKind getItem() { diff --git a/python/ql/src/semmle/python/security/injection/Path.qll b/python/ql/src/semmle/python/security/injection/Path.qll index bd318c7f1e6a..cee8c12fc162 100644 --- a/python/ql/src/semmle/python/security/injection/Path.qll +++ b/python/ql/src/semmle/python/security/injection/Path.qll @@ -36,6 +36,10 @@ class NormalizedPath extends TaintKind { this = "normalized.path.injection" } + override string repr() { + result = "normalized path" + } + } private predicate abspath_call(CallNode call, ControlFlowNode arg) { diff --git a/python/ql/test/query-tests/Security/CWE-022/PathInjection.expected b/python/ql/test/query-tests/Security/CWE-022/PathInjection.expected index 73eb7a46fe0f..861c4d09ad12 100644 --- a/python/ql/test/query-tests/Security/CWE-022/PathInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-022/PathInjection.expected @@ -1,34 +1,34 @@ edges -| ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | ../lib/os/path.py:5:12:5:12 | Taint externally controlled string at ../lib/os/path.py:5 | -| ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | ../lib/os/path.py:5:12:5:12 | Taint externally controlled string at ../lib/os/path.py:5 | -| ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | ../lib/os/path.py:5:12:5:12 | Taint externally controlled string at ../lib/os/path.py:5 | -| path_injection.py:9:12:9:23 | Taint {externally controlled string} at path_injection.py:9 | path_injection.py:9:12:9:39 | Taint externally controlled string at path_injection.py:9 | -| path_injection.py:9:12:9:39 | Taint externally controlled string at path_injection.py:9 | path_injection.py:10:40:10:43 | Taint externally controlled string at path_injection.py:10 | -| path_injection.py:10:40:10:43 | Taint externally controlled string at path_injection.py:10 | path_injection.py:10:14:10:44 | Taint externally controlled string at path_injection.py:10 | -| path_injection.py:15:12:15:23 | Taint {externally controlled string} at path_injection.py:15 | path_injection.py:15:12:15:39 | Taint externally controlled string at path_injection.py:15 | -| path_injection.py:15:12:15:39 | Taint externally controlled string at path_injection.py:15 | path_injection.py:16:56:16:59 | Taint externally controlled string at path_injection.py:16 | -| path_injection.py:16:13:16:61 | Taint normalized.path.injection at path_injection.py:16 | path_injection.py:17:14:17:18 | Taint normalized.path.injection at path_injection.py:17 | -| path_injection.py:16:30:16:60 | Taint externally controlled string at path_injection.py:16 | ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | -| path_injection.py:16:30:16:60 | Taint externally controlled string at path_injection.py:16 | path_injection.py:16:13:16:61 | Taint normalized.path.injection at path_injection.py:16 | -| path_injection.py:16:56:16:59 | Taint externally controlled string at path_injection.py:16 | path_injection.py:16:30:16:60 | Taint externally controlled string at path_injection.py:16 | -| path_injection.py:24:12:24:23 | Taint {externally controlled string} at path_injection.py:24 | path_injection.py:24:12:24:39 | Taint externally controlled string at path_injection.py:24 | -| path_injection.py:24:12:24:39 | Taint externally controlled string at path_injection.py:24 | path_injection.py:25:56:25:59 | Taint externally controlled string at path_injection.py:25 | -| path_injection.py:25:13:25:61 | Taint normalized.path.injection at path_injection.py:25 | path_injection.py:26:8:26:12 | Taint normalized.path.injection at path_injection.py:26 | -| path_injection.py:25:13:25:61 | Taint normalized.path.injection at path_injection.py:25 | path_injection.py:28:14:28:18 | Taint normalized.path.injection at path_injection.py:28 | -| path_injection.py:25:30:25:60 | Taint externally controlled string at path_injection.py:25 | ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | -| path_injection.py:25:30:25:60 | Taint externally controlled string at path_injection.py:25 | path_injection.py:25:13:25:61 | Taint normalized.path.injection at path_injection.py:25 | -| path_injection.py:25:56:25:59 | Taint externally controlled string at path_injection.py:25 | path_injection.py:25:30:25:60 | Taint externally controlled string at path_injection.py:25 | -| path_injection.py:33:12:33:23 | Taint {externally controlled string} at path_injection.py:33 | path_injection.py:33:12:33:39 | Taint externally controlled string at path_injection.py:33 | -| path_injection.py:33:12:33:39 | Taint externally controlled string at path_injection.py:33 | path_injection.py:34:56:34:59 | Taint externally controlled string at path_injection.py:34 | -| path_injection.py:34:13:34:61 | Taint normalized.path.injection at path_injection.py:34 | path_injection.py:35:8:35:12 | Taint normalized.path.injection at path_injection.py:35 | -| path_injection.py:34:30:34:60 | Taint externally controlled string at path_injection.py:34 | ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | -| path_injection.py:34:30:34:60 | Taint externally controlled string at path_injection.py:34 | path_injection.py:34:13:34:61 | Taint normalized.path.injection at path_injection.py:34 | -| path_injection.py:34:56:34:59 | Taint externally controlled string at path_injection.py:34 | path_injection.py:34:30:34:60 | Taint externally controlled string at path_injection.py:34 | +| ../lib/os/path.py:4:14:4:14 | externally controlled string | ../lib/os/path.py:5:12:5:12 | externally controlled string | +| ../lib/os/path.py:4:14:4:14 | externally controlled string | ../lib/os/path.py:5:12:5:12 | externally controlled string | +| ../lib/os/path.py:4:14:4:14 | externally controlled string | ../lib/os/path.py:5:12:5:12 | externally controlled string | +| path_injection.py:9:12:9:23 | dict of externally controlled string | path_injection.py:9:12:9:39 | externally controlled string | +| path_injection.py:9:12:9:39 | externally controlled string | path_injection.py:10:40:10:43 | externally controlled string | +| path_injection.py:10:40:10:43 | externally controlled string | path_injection.py:10:14:10:44 | externally controlled string | +| path_injection.py:15:12:15:23 | dict of externally controlled string | path_injection.py:15:12:15:39 | externally controlled string | +| path_injection.py:15:12:15:39 | externally controlled string | path_injection.py:16:56:16:59 | externally controlled string | +| path_injection.py:16:13:16:61 | normalized path | path_injection.py:17:14:17:18 | normalized path | +| path_injection.py:16:30:16:60 | externally controlled string | ../lib/os/path.py:4:14:4:14 | externally controlled string | +| path_injection.py:16:30:16:60 | externally controlled string | path_injection.py:16:13:16:61 | normalized path | +| path_injection.py:16:56:16:59 | externally controlled string | path_injection.py:16:30:16:60 | externally controlled string | +| path_injection.py:24:12:24:23 | dict of externally controlled string | path_injection.py:24:12:24:39 | externally controlled string | +| path_injection.py:24:12:24:39 | externally controlled string | path_injection.py:25:56:25:59 | externally controlled string | +| path_injection.py:25:13:25:61 | normalized path | path_injection.py:26:8:26:12 | normalized path | +| path_injection.py:25:13:25:61 | normalized path | path_injection.py:28:14:28:18 | normalized path | +| path_injection.py:25:30:25:60 | externally controlled string | ../lib/os/path.py:4:14:4:14 | externally controlled string | +| path_injection.py:25:30:25:60 | externally controlled string | path_injection.py:25:13:25:61 | normalized path | +| path_injection.py:25:56:25:59 | externally controlled string | path_injection.py:25:30:25:60 | externally controlled string | +| path_injection.py:33:12:33:23 | dict of externally controlled string | path_injection.py:33:12:33:39 | externally controlled string | +| path_injection.py:33:12:33:39 | externally controlled string | path_injection.py:34:56:34:59 | externally controlled string | +| path_injection.py:34:13:34:61 | normalized path | path_injection.py:35:8:35:12 | normalized path | +| path_injection.py:34:30:34:60 | externally controlled string | ../lib/os/path.py:4:14:4:14 | externally controlled string | +| path_injection.py:34:30:34:60 | externally controlled string | path_injection.py:34:13:34:61 | normalized path | +| path_injection.py:34:56:34:59 | externally controlled string | path_injection.py:34:30:34:60 | externally controlled string | parents -| ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | path_injection.py:16:30:16:60 | Taint externally controlled string at path_injection.py:16 | -| ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | path_injection.py:25:30:25:60 | Taint externally controlled string at path_injection.py:25 | -| ../lib/os/path.py:4:14:4:14 | Taint externally controlled string at ../lib/os/path.py:4 | path_injection.py:34:30:34:60 | Taint externally controlled string at path_injection.py:34 | +| ../lib/os/path.py:4:14:4:14 | externally controlled string | path_injection.py:16:30:16:60 | externally controlled string | +| ../lib/os/path.py:4:14:4:14 | externally controlled string | path_injection.py:25:30:25:60 | externally controlled string | +| ../lib/os/path.py:4:14:4:14 | externally controlled string | path_injection.py:34:30:34:60 | externally controlled string | #select -| path_injection.py:10:14:10:44 | argument to open() | path_injection.py:9:12:9:23 | Taint {externally controlled string} at path_injection.py:9 | path_injection.py:10:14:10:44 | Taint externally controlled string at path_injection.py:10 | This path depends on $@. | path_injection.py:9:12:9:23 | flask.request.args | a user-provided value | -| path_injection.py:17:14:17:18 | argument to open() | path_injection.py:15:12:15:23 | Taint {externally controlled string} at path_injection.py:15 | path_injection.py:17:14:17:18 | Taint normalized.path.injection at path_injection.py:17 | This path depends on $@. | path_injection.py:15:12:15:23 | flask.request.args | a user-provided value | -| path_injection.py:28:14:28:18 | argument to open() | path_injection.py:24:12:24:23 | Taint {externally controlled string} at path_injection.py:24 | path_injection.py:28:14:28:18 | Taint normalized.path.injection at path_injection.py:28 | This path depends on $@. | path_injection.py:24:12:24:23 | flask.request.args | a user-provided value | +| path_injection.py:10:14:10:44 | argument to open() | path_injection.py:9:12:9:23 | dict of externally controlled string | path_injection.py:10:14:10:44 | externally controlled string | This path depends on $@. | path_injection.py:9:12:9:23 | flask.request.args | a user-provided value | +| path_injection.py:17:14:17:18 | argument to open() | path_injection.py:15:12:15:23 | dict of externally controlled string | path_injection.py:17:14:17:18 | normalized path | This path depends on $@. | path_injection.py:15:12:15:23 | flask.request.args | a user-provided value | +| path_injection.py:28:14:28:18 | argument to open() | path_injection.py:24:12:24:23 | dict of externally controlled string | path_injection.py:28:14:28:18 | normalized path | This path depends on $@. | path_injection.py:24:12:24:23 | flask.request.args | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-078/CommandInjection.expected b/python/ql/test/query-tests/Security/CWE-078/CommandInjection.expected index 09953ec851eb..8bdfeac00027 100644 --- a/python/ql/test/query-tests/Security/CWE-078/CommandInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-078/CommandInjection.expected @@ -1,19 +1,18 @@ edges -| command_injection.py:10:13:10:24 | Taint {externally controlled string} at command_injection.py:10 | command_injection.py:10:13:10:41 | Taint externally controlled string at command_injection.py:10 | -| command_injection.py:10:13:10:41 | Taint externally controlled string at command_injection.py:10 | command_injection.py:12:23:12:27 | Taint externally controlled string at command_injection.py:12 | -| command_injection.py:12:15:12:27 | Taint externally controlled string at command_injection.py:12 | ../lib/os/__init__.py:1:12:1:14 | Taint externally controlled string at ../lib/os/__init__.py:1 | -| command_injection.py:12:23:12:27 | Taint externally controlled string at command_injection.py:12 | command_injection.py:12:15:12:27 | Taint externally controlled string at command_injection.py:12 | -| command_injection.py:17:13:17:24 | Taint {externally controlled string} at command_injection.py:17 | command_injection.py:17:13:17:41 | Taint externally controlled string at command_injection.py:17 | -| command_injection.py:17:13:17:41 | Taint externally controlled string at command_injection.py:17 | command_injection.py:19:29:19:33 | Taint externally controlled string at command_injection.py:19 | -| command_injection.py:19:29:19:33 | Taint externally controlled string at command_injection.py:19 | command_injection.py:19:22:19:34 | Taint [externally controlled string] at command_injection.py:19 | -| command_injection.py:24:11:24:22 | Taint {externally controlled string} at command_injection.py:24 | command_injection.py:24:11:24:37 | Taint externally controlled string at command_injection.py:24 | -| command_injection.py:24:11:24:37 | Taint externally controlled string at command_injection.py:24 | command_injection.py:25:23:25:25 | Taint externally controlled string at command_injection.py:25 | -| command_injection.py:25:23:25:25 | Taint externally controlled string at command_injection.py:25 | command_injection.py:25:22:25:36 | Taint [externally controlled string] at command_injection.py:25 | -| command_injection.py:25:23:25:25 | Taint externally controlled string at command_injection.py:25 | command_injection.py:25:22:25:36 | Taint sequence[externally controlled string][0] at command_injection.py:25 | +| command_injection.py:10:13:10:24 | dict of externally controlled string | command_injection.py:10:13:10:41 | externally controlled string | +| command_injection.py:10:13:10:41 | externally controlled string | command_injection.py:12:23:12:27 | externally controlled string | +| command_injection.py:12:15:12:27 | externally controlled string | ../lib/os/__init__.py:1:12:1:14 | externally controlled string | +| command_injection.py:12:23:12:27 | externally controlled string | command_injection.py:12:15:12:27 | externally controlled string | +| command_injection.py:17:13:17:24 | dict of externally controlled string | command_injection.py:17:13:17:41 | externally controlled string | +| command_injection.py:17:13:17:41 | externally controlled string | command_injection.py:19:29:19:33 | externally controlled string | +| command_injection.py:19:29:19:33 | externally controlled string | command_injection.py:19:22:19:34 | sequence of externally controlled string | +| command_injection.py:24:11:24:22 | dict of externally controlled string | command_injection.py:24:11:24:37 | externally controlled string | +| command_injection.py:24:11:24:37 | externally controlled string | command_injection.py:25:23:25:25 | externally controlled string | +| command_injection.py:25:23:25:25 | externally controlled string | command_injection.py:25:22:25:36 | first item in sequence of externally controlled string | +| command_injection.py:25:23:25:25 | externally controlled string | command_injection.py:25:22:25:36 | sequence of externally controlled string | parents -| ../lib/os/__init__.py:1:12:1:14 | Taint externally controlled string at ../lib/os/__init__.py:1 | command_injection.py:12:15:12:27 | Taint externally controlled string at command_injection.py:12 | +| ../lib/os/__init__.py:1:12:1:14 | externally controlled string | command_injection.py:12:15:12:27 | externally controlled string | #select -| command_injection.py:12:15:12:27 | shell command | command_injection.py:10:13:10:24 | Taint {externally controlled string} at command_injection.py:10 | command_injection.py:12:15:12:27 | Taint externally controlled string at command_injection.py:12 | This command depends on $@. | command_injection.py:10:13:10:24 | flask.request.args | a user-provided value | -| command_injection.py:19:22:19:34 | shell command | command_injection.py:17:13:17:24 | Taint {externally controlled string} at command_injection.py:17 | command_injection.py:19:22:19:34 | Taint [externally controlled string] at command_injection.py:19 | This command depends on $@. | command_injection.py:17:13:17:24 | flask.request.args | a user-provided value | -| command_injection.py:25:22:25:36 | OS command first argument | command_injection.py:24:11:24:22 | Taint {externally controlled string} at command_injection.py:24 | command_injection.py:25:22:25:36 | Taint [externally controlled string] at command_injection.py:25 | This command depends on $@. | command_injection.py:24:11:24:22 | flask.request.args | a user-provided value | -| command_injection.py:25:22:25:36 | OS command first argument | command_injection.py:24:11:24:22 | Taint {externally controlled string} at command_injection.py:24 | command_injection.py:25:22:25:36 | Taint sequence[externally controlled string][0] at command_injection.py:25 | This command depends on $@. | command_injection.py:24:11:24:22 | flask.request.args | a user-provided value | +| command_injection.py:12:15:12:27 | shell command | command_injection.py:10:13:10:24 | dict of externally controlled string | command_injection.py:12:15:12:27 | externally controlled string | This command depends on $@. | command_injection.py:10:13:10:24 | flask.request.args | a user-provided value | +| command_injection.py:19:22:19:34 | shell command | command_injection.py:17:13:17:24 | dict of externally controlled string | command_injection.py:19:22:19:34 | sequence of externally controlled string | This command depends on $@. | command_injection.py:17:13:17:24 | flask.request.args | a user-provided value | +| command_injection.py:25:22:25:36 | OS command first argument | command_injection.py:24:11:24:22 | dict of externally controlled string | command_injection.py:25:22:25:36 | first item in sequence of externally controlled string | This command depends on $@. | command_injection.py:24:11:24:22 | flask.request.args | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected b/python/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected index 1f1e49293fe9..f53b054990a5 100644 --- a/python/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected +++ b/python/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected @@ -1,13 +1,13 @@ edges -| ../lib/flask/__init__.py:14:19:14:20 | Taint externally controlled string at ../lib/flask/__init__.py:14 | ../lib/flask/__init__.py:15:19:15:20 | Taint externally controlled string at ../lib/flask/__init__.py:15 | -| ../lib/flask/__init__.py:14:19:14:20 | Taint externally controlled string at ../lib/flask/__init__.py:14 | ../lib/flask/__init__.py:16:25:16:26 | Taint externally controlled string at ../lib/flask/__init__.py:16 | -| reflected_xss.py:7:18:7:29 | Taint {externally controlled string} at reflected_xss.py:7 | reflected_xss.py:7:18:7:45 | Taint externally controlled string at reflected_xss.py:7 | -| reflected_xss.py:7:18:7:45 | Taint externally controlled string at reflected_xss.py:7 | reflected_xss.py:8:44:8:53 | Taint externally controlled string at reflected_xss.py:8 | -| reflected_xss.py:8:26:8:53 | Taint externally controlled string at reflected_xss.py:8 | ../lib/flask/__init__.py:14:19:14:20 | Taint externally controlled string at ../lib/flask/__init__.py:14 | -| reflected_xss.py:8:44:8:53 | Taint externally controlled string at reflected_xss.py:8 | reflected_xss.py:8:26:8:53 | Taint externally controlled string at reflected_xss.py:8 | -| reflected_xss.py:12:18:12:29 | Taint {externally controlled string} at reflected_xss.py:12 | reflected_xss.py:12:18:12:45 | Taint externally controlled string at reflected_xss.py:12 | -| reflected_xss.py:12:18:12:45 | Taint externally controlled string at reflected_xss.py:12 | reflected_xss.py:13:51:13:60 | Taint externally controlled string at reflected_xss.py:13 | +| ../lib/flask/__init__.py:14:19:14:20 | externally controlled string | ../lib/flask/__init__.py:15:19:15:20 | externally controlled string | +| ../lib/flask/__init__.py:14:19:14:20 | externally controlled string | ../lib/flask/__init__.py:16:25:16:26 | externally controlled string | +| reflected_xss.py:7:18:7:29 | dict of externally controlled string | reflected_xss.py:7:18:7:45 | externally controlled string | +| reflected_xss.py:7:18:7:45 | externally controlled string | reflected_xss.py:8:44:8:53 | externally controlled string | +| reflected_xss.py:8:26:8:53 | externally controlled string | ../lib/flask/__init__.py:14:19:14:20 | externally controlled string | +| reflected_xss.py:8:44:8:53 | externally controlled string | reflected_xss.py:8:26:8:53 | externally controlled string | +| reflected_xss.py:12:18:12:29 | dict of externally controlled string | reflected_xss.py:12:18:12:45 | externally controlled string | +| reflected_xss.py:12:18:12:45 | externally controlled string | reflected_xss.py:13:51:13:60 | externally controlled string | parents -| ../lib/flask/__init__.py:14:19:14:20 | Taint externally controlled string at ../lib/flask/__init__.py:14 | reflected_xss.py:8:26:8:53 | Taint externally controlled string at reflected_xss.py:8 | +| ../lib/flask/__init__.py:14:19:14:20 | externally controlled string | reflected_xss.py:8:26:8:53 | externally controlled string | #select -| ../lib/flask/__init__.py:16:25:16:26 | flask.response.argument | reflected_xss.py:7:18:7:29 | Taint {externally controlled string} at reflected_xss.py:7 | ../lib/flask/__init__.py:16:25:16:26 | Taint externally controlled string at ../lib/flask/__init__.py:16 | Cross-site scripting vulnerability due to $@. | reflected_xss.py:7:18:7:29 | flask.request.args | user-provided value | +| ../lib/flask/__init__.py:16:25:16:26 | flask.response.argument | reflected_xss.py:7:18:7:29 | dict of externally controlled string | ../lib/flask/__init__.py:16:25:16:26 | externally controlled string | Cross-site scripting vulnerability due to $@. | reflected_xss.py:7:18:7:29 | flask.request.args | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-089/SqlInjection.expected b/python/ql/test/query-tests/Security/CWE-089/SqlInjection.expected index 33d87c296d6e..1555b7cd7793 100644 --- a/python/ql/test/query-tests/Security/CWE-089/SqlInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-089/SqlInjection.expected @@ -1,25 +1,25 @@ edges -| sql_injection.py:9:15:9:21 | Taint django.request.HttpRequest at sql_injection.py:9 | sql_injection.py:11:8:11:14 | Taint django.request.HttpRequest at sql_injection.py:11 | -| sql_injection.py:9:15:9:21 | Taint django.request.HttpRequest at sql_injection.py:9 | sql_injection.py:12:16:12:22 | Taint django.request.HttpRequest at sql_injection.py:12 | -| sql_injection.py:12:16:12:22 | Taint django.request.HttpRequest at sql_injection.py:12 | sql_injection.py:12:16:12:27 | Taint django.http.request.QueryDict at sql_injection.py:12 | -| sql_injection.py:12:16:12:27 | Taint django.http.request.QueryDict at sql_injection.py:12 | sql_injection.py:12:16:12:39 | Taint externally controlled string at sql_injection.py:12 | -| sql_injection.py:12:16:12:39 | Taint externally controlled string at sql_injection.py:12 | sql_injection.py:16:62:16:65 | Taint externally controlled string at sql_injection.py:16 | -| sql_injection.py:12:16:12:39 | Taint externally controlled string at sql_injection.py:12 | sql_injection.py:19:63:19:66 | Taint externally controlled string at sql_injection.py:19 | -| sql_injection.py:12:16:12:39 | Taint externally controlled string at sql_injection.py:12 | sql_injection.py:22:88:22:91 | Taint externally controlled string at sql_injection.py:22 | -| sql_injection.py:12:16:12:39 | Taint externally controlled string at sql_injection.py:12 | sql_injection.py:23:76:23:79 | Taint externally controlled string at sql_injection.py:23 | -| sql_injection.py:12:16:12:39 | Taint externally controlled string at sql_injection.py:12 | sql_injection.py:24:78:24:81 | Taint externally controlled string at sql_injection.py:24 | -| sql_injection.py:13:16:13:34 | Taint django.db.connection.cursor at sql_injection.py:13 | sql_injection.py:15:9:15:12 | Taint django.db.connection.cursor at sql_injection.py:15 | -| sql_injection.py:13:16:13:34 | Taint django.db.connection.cursor at sql_injection.py:13 | sql_injection.py:18:9:18:12 | Taint django.db.connection.cursor at sql_injection.py:18 | -| sql_injection.py:19:63:19:66 | Taint externally controlled string at sql_injection.py:19 | sql_injection.py:19:13:19:66 | Taint externally controlled string at sql_injection.py:19 | -| sql_injection.py:22:9:22:20 | Taint django.db.models.Model.objects at sql_injection.py:22 | sql_injection.py:22:9:22:93 | Taint django.db.models.Model.objects at sql_injection.py:22 | -| sql_injection.py:22:88:22:91 | Taint externally controlled string at sql_injection.py:22 | sql_injection.py:22:38:22:91 | Taint externally controlled string at sql_injection.py:22 | -| sql_injection.py:23:9:23:20 | Taint django.db.models.Model.objects at sql_injection.py:23 | sql_injection.py:23:9:23:80 | Taint django.db.models.Model.objects at sql_injection.py:23 | -| sql_injection.py:23:76:23:79 | Taint externally controlled string at sql_injection.py:23 | sql_injection.py:23:26:23:79 | Taint externally controlled string at sql_injection.py:23 | -| sql_injection.py:24:9:24:20 | Taint django.db.models.Model.objects at sql_injection.py:24 | sql_injection.py:24:9:24:82 | Taint django.db.models.Model.objects at sql_injection.py:24 | -| sql_injection.py:24:78:24:81 | Taint externally controlled string at sql_injection.py:24 | sql_injection.py:24:28:24:81 | Taint externally controlled string at sql_injection.py:24 | +| sql_injection.py:9:15:9:21 | django.request.HttpRequest | sql_injection.py:11:8:11:14 | django.request.HttpRequest | +| sql_injection.py:9:15:9:21 | django.request.HttpRequest | sql_injection.py:12:16:12:22 | django.request.HttpRequest | +| sql_injection.py:12:16:12:22 | django.request.HttpRequest | sql_injection.py:12:16:12:27 | django.http.request.QueryDict | +| sql_injection.py:12:16:12:27 | django.http.request.QueryDict | sql_injection.py:12:16:12:39 | externally controlled string | +| sql_injection.py:12:16:12:39 | externally controlled string | sql_injection.py:16:62:16:65 | externally controlled string | +| sql_injection.py:12:16:12:39 | externally controlled string | sql_injection.py:19:63:19:66 | externally controlled string | +| sql_injection.py:12:16:12:39 | externally controlled string | sql_injection.py:22:88:22:91 | externally controlled string | +| sql_injection.py:12:16:12:39 | externally controlled string | sql_injection.py:23:76:23:79 | externally controlled string | +| sql_injection.py:12:16:12:39 | externally controlled string | sql_injection.py:24:78:24:81 | externally controlled string | +| sql_injection.py:13:16:13:34 | django.db.connection.cursor | sql_injection.py:15:9:15:12 | django.db.connection.cursor | +| sql_injection.py:13:16:13:34 | django.db.connection.cursor | sql_injection.py:18:9:18:12 | django.db.connection.cursor | +| sql_injection.py:19:63:19:66 | externally controlled string | sql_injection.py:19:13:19:66 | externally controlled string | +| sql_injection.py:22:9:22:20 | django.db.models.Model.objects | sql_injection.py:22:9:22:93 | django.db.models.Model.objects | +| sql_injection.py:22:88:22:91 | externally controlled string | sql_injection.py:22:38:22:91 | externally controlled string | +| sql_injection.py:23:9:23:20 | django.db.models.Model.objects | sql_injection.py:23:9:23:80 | django.db.models.Model.objects | +| sql_injection.py:23:76:23:79 | externally controlled string | sql_injection.py:23:26:23:79 | externally controlled string | +| sql_injection.py:24:9:24:20 | django.db.models.Model.objects | sql_injection.py:24:9:24:82 | django.db.models.Model.objects | +| sql_injection.py:24:78:24:81 | externally controlled string | sql_injection.py:24:28:24:81 | externally controlled string | parents #select -| sql_injection.py:19:13:19:66 | db.connection.execute | sql_injection.py:9:15:9:21 | Taint django.request.HttpRequest at sql_injection.py:9 | sql_injection.py:19:13:19:66 | Taint externally controlled string at sql_injection.py:19 | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | Django request source | a user-provided value | -| sql_injection.py:22:38:22:91 | django.db.models.expressions.RawSQL(sink,...) | sql_injection.py:9:15:9:21 | Taint django.request.HttpRequest at sql_injection.py:9 | sql_injection.py:22:38:22:91 | Taint externally controlled string at sql_injection.py:22 | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | Django request source | a user-provided value | -| sql_injection.py:23:26:23:79 | django.models.QuerySet.raw(sink,...) | sql_injection.py:9:15:9:21 | Taint django.request.HttpRequest at sql_injection.py:9 | sql_injection.py:23:26:23:79 | Taint externally controlled string at sql_injection.py:23 | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | Django request source | a user-provided value | -| sql_injection.py:24:28:24:81 | django.models.QuerySet.extra(sink,...) | sql_injection.py:9:15:9:21 | Taint django.request.HttpRequest at sql_injection.py:9 | sql_injection.py:24:28:24:81 | Taint externally controlled string at sql_injection.py:24 | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | Django request source | a user-provided value | +| sql_injection.py:19:13:19:66 | db.connection.execute | sql_injection.py:9:15:9:21 | django.request.HttpRequest | sql_injection.py:19:13:19:66 | externally controlled string | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | Django request source | a user-provided value | +| sql_injection.py:22:38:22:91 | django.db.models.expressions.RawSQL(sink,...) | sql_injection.py:9:15:9:21 | django.request.HttpRequest | sql_injection.py:22:38:22:91 | externally controlled string | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | Django request source | a user-provided value | +| sql_injection.py:23:26:23:79 | django.models.QuerySet.raw(sink,...) | sql_injection.py:9:15:9:21 | django.request.HttpRequest | sql_injection.py:23:26:23:79 | externally controlled string | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | Django request source | a user-provided value | +| sql_injection.py:24:28:24:81 | django.models.QuerySet.extra(sink,...) | sql_injection.py:9:15:9:21 | django.request.HttpRequest | sql_injection.py:24:28:24:81 | externally controlled string | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | Django request source | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-094/CodeInjection.expected b/python/ql/test/query-tests/Security/CWE-094/CodeInjection.expected index 48980e5b6a93..8c621808c14d 100644 --- a/python/ql/test/query-tests/Security/CWE-094/CodeInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-094/CodeInjection.expected @@ -1,12 +1,12 @@ edges -| code_injection.py:4:20:4:26 | Taint django.request.HttpRequest at code_injection.py:4 | code_injection.py:5:8:5:14 | Taint django.request.HttpRequest at code_injection.py:5 | -| code_injection.py:4:20:4:26 | Taint django.request.HttpRequest at code_injection.py:4 | code_injection.py:6:22:6:28 | Taint django.request.HttpRequest at code_injection.py:6 | -| code_injection.py:6:22:6:28 | Taint django.request.HttpRequest at code_injection.py:6 | code_injection.py:6:22:6:33 | Taint django.http.request.QueryDict at code_injection.py:6 | -| code_injection.py:6:22:6:33 | Taint django.http.request.QueryDict at code_injection.py:6 | code_injection.py:6:22:6:55 | Taint externally controlled string at code_injection.py:6 | -| code_injection.py:6:22:6:55 | Taint externally controlled string at code_injection.py:6 | code_injection.py:7:34:7:43 | Taint externally controlled string at code_injection.py:7 | -| code_injection.py:7:34:7:43 | Taint externally controlled string at code_injection.py:7 | ../lib/base64.py:1:18:1:18 | Taint externally controlled string at ../lib/base64.py:1 | -| code_injection.py:7:34:7:43 | Taint externally controlled string at code_injection.py:7 | code_injection.py:7:14:7:44 | Taint externally controlled string at code_injection.py:7 | +| code_injection.py:4:20:4:26 | django.request.HttpRequest | code_injection.py:5:8:5:14 | django.request.HttpRequest | +| code_injection.py:4:20:4:26 | django.request.HttpRequest | code_injection.py:6:22:6:28 | django.request.HttpRequest | +| code_injection.py:6:22:6:28 | django.request.HttpRequest | code_injection.py:6:22:6:33 | django.http.request.QueryDict | +| code_injection.py:6:22:6:33 | django.http.request.QueryDict | code_injection.py:6:22:6:55 | externally controlled string | +| code_injection.py:6:22:6:55 | externally controlled string | code_injection.py:7:34:7:43 | externally controlled string | +| code_injection.py:7:34:7:43 | externally controlled string | ../lib/base64.py:1:18:1:18 | externally controlled string | +| code_injection.py:7:34:7:43 | externally controlled string | code_injection.py:7:14:7:44 | externally controlled string | parents -| ../lib/base64.py:1:18:1:18 | Taint externally controlled string at ../lib/base64.py:1 | code_injection.py:7:34:7:43 | Taint externally controlled string at code_injection.py:7 | +| ../lib/base64.py:1:18:1:18 | externally controlled string | code_injection.py:7:34:7:43 | externally controlled string | #select -| code_injection.py:7:14:7:44 | exec or eval | code_injection.py:4:20:4:26 | Taint django.request.HttpRequest at code_injection.py:4 | code_injection.py:7:14:7:44 | Taint externally controlled string at code_injection.py:7 | $@ flows to here and is interpreted as code. | code_injection.py:4:20:4:26 | Django request source | User-provided value | +| code_injection.py:7:14:7:44 | exec or eval | code_injection.py:4:20:4:26 | django.request.HttpRequest | code_injection.py:7:14:7:44 | externally controlled string | $@ flows to here and is interpreted as code. | code_injection.py:4:20:4:26 | Django request source | User-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected b/python/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected index c5d0f64988e5..8a4074a332cb 100644 --- a/python/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected +++ b/python/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected @@ -1,11 +1,11 @@ edges -| test.py:33:15:33:36 | Taint exception.info at test.py:33 | test.py:34:29:34:31 | Taint exception.info at test.py:34 | -| test.py:34:29:34:31 | Taint exception.info at test.py:34 | test.py:36:18:36:20 | Taint exception.info at test.py:36 | -| test.py:36:18:36:20 | Taint exception.info at test.py:36 | test.py:37:25:37:27 | Taint exception.info at test.py:37 | -| test.py:37:12:37:27 | Taint exception.info at test.py:37 | test.py:34:16:34:32 | Taint exception.info at test.py:34 | -| test.py:37:25:37:27 | Taint exception.info at test.py:37 | test.py:37:12:37:27 | Taint exception.info at test.py:37 | +| test.py:33:15:33:36 | exception info | test.py:34:29:34:31 | exception info | +| test.py:34:29:34:31 | exception info | test.py:36:18:36:20 | exception info | +| test.py:36:18:36:20 | exception info | test.py:37:25:37:27 | exception info | +| test.py:37:12:37:27 | exception info | test.py:34:16:34:32 | exception info | +| test.py:37:25:37:27 | exception info | test.py:37:12:37:27 | exception info | parents -| test.py:36:18:36:20 | Taint exception.info at test.py:36 | test.py:34:29:34:31 | Taint exception.info at test.py:34 | +| test.py:36:18:36:20 | exception info | test.py:34:29:34:31 | exception info | #select -| test.py:16:16:16:37 | flask.routed.response | test.py:16:16:16:37 | Taint exception.info at test.py:16 | test.py:16:16:16:37 | Taint exception.info at test.py:16 | $@ may be exposed to an external user | test.py:16:16:16:37 | exception.info.source | Error information | -| test.py:34:16:34:32 | flask.routed.response | test.py:33:15:33:36 | Taint exception.info at test.py:33 | test.py:34:16:34:32 | Taint exception.info at test.py:34 | $@ may be exposed to an external user | test.py:33:15:33:36 | exception.info.source | Error information | +| test.py:16:16:16:37 | flask.routed.response | test.py:16:16:16:37 | exception info | test.py:16:16:16:37 | exception info | $@ may be exposed to an external user | test.py:16:16:16:37 | exception.info.source | Error information | +| test.py:34:16:34:32 | flask.routed.response | test.py:33:15:33:36 | exception info | test.py:34:16:34:32 | exception info | $@ may be exposed to an external user | test.py:33:15:33:36 | exception.info.source | Error information | diff --git a/python/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected b/python/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected index 522188d9152f..79dee42edb4e 100644 --- a/python/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected +++ b/python/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected @@ -1,12 +1,12 @@ edges -| test.py:11:15:11:26 | Taint {externally controlled string} at test.py:11 | test.py:11:15:11:41 | Taint externally controlled string at test.py:11 | -| test.py:11:15:11:41 | Taint externally controlled string at test.py:11 | test.py:12:18:12:24 | Taint externally controlled string at test.py:12 | -| test.py:11:15:11:41 | Taint externally controlled string at test.py:11 | test.py:13:15:13:21 | Taint externally controlled string at test.py:13 | -| test.py:11:15:11:41 | Taint externally controlled string at test.py:11 | test.py:14:19:14:25 | Taint externally controlled string at test.py:14 | -| test.py:13:15:13:21 | Taint externally controlled string at test.py:13 | ../lib/yaml.py:1:10:1:10 | Taint externally controlled string at ../lib/yaml.py:1 | +| test.py:11:15:11:26 | dict of externally controlled string | test.py:11:15:11:41 | externally controlled string | +| test.py:11:15:11:41 | externally controlled string | test.py:12:18:12:24 | externally controlled string | +| test.py:11:15:11:41 | externally controlled string | test.py:13:15:13:21 | externally controlled string | +| test.py:11:15:11:41 | externally controlled string | test.py:14:19:14:25 | externally controlled string | +| test.py:13:15:13:21 | externally controlled string | ../lib/yaml.py:1:10:1:10 | externally controlled string | parents -| ../lib/yaml.py:1:10:1:10 | Taint externally controlled string at ../lib/yaml.py:1 | test.py:13:15:13:21 | Taint externally controlled string at test.py:13 | +| ../lib/yaml.py:1:10:1:10 | externally controlled string | test.py:13:15:13:21 | externally controlled string | #select -| test.py:12:18:12:24 | unpickling untrusted data | test.py:11:15:11:26 | Taint {externally controlled string} at test.py:11 | test.py:12:18:12:24 | Taint externally controlled string at test.py:12 | Deserializing of $@. | test.py:11:15:11:26 | flask.request.args | untrusted input | -| test.py:13:15:13:21 | yaml.load vulnerability | test.py:11:15:11:26 | Taint {externally controlled string} at test.py:11 | test.py:13:15:13:21 | Taint externally controlled string at test.py:13 | Deserializing of $@. | test.py:11:15:11:26 | flask.request.args | untrusted input | -| test.py:14:19:14:25 | unmarshaling vulnerability | test.py:11:15:11:26 | Taint {externally controlled string} at test.py:11 | test.py:14:19:14:25 | Taint externally controlled string at test.py:14 | Deserializing of $@. | test.py:11:15:11:26 | flask.request.args | untrusted input | +| test.py:12:18:12:24 | unpickling untrusted data | test.py:11:15:11:26 | dict of externally controlled string | test.py:12:18:12:24 | externally controlled string | Deserializing of $@. | test.py:11:15:11:26 | flask.request.args | untrusted input | +| test.py:13:15:13:21 | yaml.load vulnerability | test.py:11:15:11:26 | dict of externally controlled string | test.py:13:15:13:21 | externally controlled string | Deserializing of $@. | test.py:11:15:11:26 | flask.request.args | untrusted input | +| test.py:14:19:14:25 | unmarshaling vulnerability | test.py:11:15:11:26 | dict of externally controlled string | test.py:14:19:14:25 | externally controlled string | Deserializing of $@. | test.py:11:15:11:26 | flask.request.args | untrusted input | diff --git a/python/ql/test/query-tests/Security/CWE-601/UrlRedirect.expected b/python/ql/test/query-tests/Security/CWE-601/UrlRedirect.expected index c4c0df06c12e..5de71ec5ee56 100644 --- a/python/ql/test/query-tests/Security/CWE-601/UrlRedirect.expected +++ b/python/ql/test/query-tests/Security/CWE-601/UrlRedirect.expected @@ -1,10 +1,10 @@ edges -| test.py:7:22:7:33 | Taint {externally controlled string} at test.py:7 | test.py:7:22:7:51 | Taint externally controlled string at test.py:7 | -| test.py:7:22:7:51 | Taint externally controlled string at test.py:7 | test.py:8:21:8:26 | Taint externally controlled string at test.py:8 | -| test.py:8:21:8:26 | Taint externally controlled string at test.py:8 | ../lib/flask/__init__.py:11:14:11:21 | Taint externally controlled string at ../lib/flask/__init__.py:11 | -| test.py:15:17:15:28 | Taint {externally controlled string} at test.py:15 | test.py:15:17:15:42 | Taint externally controlled string at test.py:15 | -| test.py:15:17:15:42 | Taint externally controlled string at test.py:15 | test.py:17:13:17:21 | Taint externally controlled string at test.py:17 | +| test.py:7:22:7:33 | dict of externally controlled string | test.py:7:22:7:51 | externally controlled string | +| test.py:7:22:7:51 | externally controlled string | test.py:8:21:8:26 | externally controlled string | +| test.py:8:21:8:26 | externally controlled string | ../lib/flask/__init__.py:11:14:11:21 | externally controlled string | +| test.py:15:17:15:28 | dict of externally controlled string | test.py:15:17:15:42 | externally controlled string | +| test.py:15:17:15:42 | externally controlled string | test.py:17:13:17:21 | externally controlled string | parents -| ../lib/flask/__init__.py:11:14:11:21 | Taint externally controlled string at ../lib/flask/__init__.py:11 | test.py:8:21:8:26 | Taint externally controlled string at test.py:8 | +| ../lib/flask/__init__.py:11:14:11:21 | externally controlled string | test.py:8:21:8:26 | externally controlled string | #select -| test.py:8:21:8:26 | flask.redirect | test.py:7:22:7:33 | Taint {externally controlled string} at test.py:7 | test.py:8:21:8:26 | Taint externally controlled string at test.py:8 | Untrusted URL redirection due to $@. | test.py:7:22:7:33 | flask.request.args | a user-provided value | +| test.py:8:21:8:26 | flask.redirect | test.py:7:22:7:33 | dict of externally controlled string | test.py:8:21:8:26 | externally controlled string | Untrusted URL redirection due to $@. | test.py:7:22:7:33 | flask.request.args | a user-provided value |