From a398f707fe50aa119dc200f1aa991dd5dca1a0da Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 19 Nov 2024 16:34:59 +0000 Subject: [PATCH 1/3] Add some test cases for flow involving global variables and captured variables --- .../global-or-captured-vars/test.expected | 4 + .../dataflow/global-or-captured-vars/test.py | 88 +++++++++++++++++++ .../dataflow/global-or-captured-vars/test.ql | 3 + 3 files changed, 95 insertions(+) create mode 100644 python/ql/test/library-tests/dataflow/global-or-captured-vars/test.expected create mode 100644 python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py create mode 100644 python/ql/test/library-tests/dataflow/global-or-captured-vars/test.ql diff --git a/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.expected b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.expected new file mode 100644 index 000000000000..366de37b8677 --- /dev/null +++ b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.expected @@ -0,0 +1,4 @@ +argumentToEnsureNotTaintedNotMarkedAsSpurious +untaintedArgumentToEnsureTaintedNotMarkedAsMissing +testFailures +failures diff --git a/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py new file mode 100644 index 000000000000..3874d67e4a48 --- /dev/null +++ b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py @@ -0,0 +1,88 @@ +import threading +import time + +# Test 1 +# TP - Flow is tracked through a global variable +foo1 = None + +def bar1(): + time.sleep(1) + ensure_tainted(foo1) # $tainted + +# The intent of these tests is to test how dataflow is handled through shared state accessed by different threads; +# but the presense or absense of the actual call to start a thread does not affect the results (there is no special modelling for Thread) +# threading.Thread(target=bar).start() + +foo1 = TAINTED_STRING + +# Test 2 +# FN - Flow is *not* tracked through an access path on a global variable +foo2 = [] + +def bar2(): + time.sleep(1) + ensure_tainted(foo2[0]) # $MISSING:tainted + +threading.Thread(target=bar2).start() + +foo2.append(TAINTED_STRING) + +# Test 3 +# FN - Flow is not found even when there is a direct call +foo3 = [] + +def bar3(): + time.sleep(1) + ensure_tainted(foo2[0]) # $MISSING:tainted + +foo3.append(TAINTED_STRING) +bar3() + +# Tast 4 +# TP - Sanity check: Flow is found through a ListElement directly without a call +foo4 = [] +foo4.append(TAINTED_STRING) +ensure_tainted(foo4[0]) # $tainted + +# Test 5 +# FN - Flow is *not* tracked through a shared captured but non-global variable +def test5(): + foo5 = None + + def bar5(): + time.sleep(1) + ensure_tainted(foo5) # $MISSING:tainted + + threading.Thread(target=bar5).start() # Only the presense of this thread call makes this an FN rather than a TN + + foo5 = TAINTED_STRING + + # Test 6 + # TP - Flow is tracked through a shared captured but non-global variable with a direct call +def test6(): + foo6 = [] + + def bar6(): + time.sleep(1) + ensure_tainted(foo[0]) # $tainted + + foo6.append(TAINTED_STRING) + bar6() + + +# Test 7 +# FN - Flow is *not* found through an access path on a global variable that's also used as a parameter +# We'd like to cover this case in order to be able to cover this CVE: https://github.com/github/codeql-python-CVE-coverage/issues/3176 + +foo7 = [] + +def bar7(): + time.sleep(1) + ensure_tainted(foo7[0]) # $MISSING: tainted + +def baz7(loc_foo): + loc_foo.append(TAINTED_STRING) + +threading.Thread(target=bar7).start() + +baz7(foo7) \ No newline at end of file diff --git a/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.ql b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.ql new file mode 100644 index 000000000000..dd01b5d3e341 --- /dev/null +++ b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.ql @@ -0,0 +1,3 @@ +import python +import experimental.meta.InlineTaintTest +import MakeInlineTaintTest From 9b4b01a442dc37f83e5d0ac450f6653e6d1bc8c9 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 20 Nov 2024 10:59:27 +0000 Subject: [PATCH 2/3] Fix typo --- .../test/library-tests/dataflow/global-or-captured-vars/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py index 3874d67e4a48..f60458ca4f9e 100644 --- a/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py +++ b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py @@ -64,7 +64,7 @@ def test6(): def bar6(): time.sleep(1) - ensure_tainted(foo[0]) # $tainted + ensure_tainted(foo6[0]) # $tainted foo6.append(TAINTED_STRING) bar6() From 52cd7f2c5c9d49b14975d02abf944500b5975c18 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 20 Nov 2024 11:22:42 +0000 Subject: [PATCH 3/3] Add 2 more cases --- .../dataflow/global-or-captured-vars/test.py | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py index f60458ca4f9e..7719021890f8 100644 --- a/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py +++ b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.py @@ -85,4 +85,34 @@ def baz7(loc_foo): threading.Thread(target=bar7).start() -baz7(foo7) \ No newline at end of file +baz7(foo7) + +# Test 8 +# FN - Flow is also *not* found in the above case through a direct call + +foo8 = [] + +def bar8(): + time.sleep(1) + ensure_tainted(foo8[0]) # $MISSING: tainted + +def baz8(loc_foo): + loc_foo.append(TAINTED_STRING) + +baz8(foo8) +bar8() + +# Test 9 +# TP - Flow is found in the above case when the variable is captured rather than global + +def test9(): + foo9 = [] + def bar9(): + time.sleep(1) + ensure_tainted(foo9[0]) # $tainted + + def baz9(loc_foo): + loc_foo.append(TAINTED_STRING) + + baz9(foo9) + bar9() \ No newline at end of file