From 882000afb3017fcc2814c3dfaa0aa9cd88bdc83e Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 16 Jun 2022 11:47:34 +0200 Subject: [PATCH] python: `not` is confusing our logic - added `is_unsafe` - added "negated version" of two tests. These versions do not use `not` and the analysis gets the taint right. --- .../customSanitizer/InlineTaintTest.expected | 16 ++++++------ .../customSanitizer/InlineTaintTest.ql | 8 ++++++ .../customSanitizer/test_logical.py | 25 +++++++++++++++++++ 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected index c8c41375538..6e67de96c62 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected +++ b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected @@ -6,12 +6,14 @@ isSanitizer | TestTaintTrackingConfiguration | test.py:34:39:34:39 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test.py:52:28:52:28 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test.py:66:10:66:29 | ControlFlowNode for emulated_escaping() | -| TestTaintTrackingConfiguration | test_logical.py:30:28:30:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:45:28:45:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:50:28:50:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:89:28:89:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:100:28:100:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:145:28:145:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:33:28:33:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:48:28:48:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:53:28:53:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:92:28:92:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:103:28:103:28 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test_logical.py:148:28:148:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:155:28:155:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:151:28:151:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:158:28:158:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:176:24:176:24 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:193:24:193:24 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test_reference.py:31:28:31:28 | ControlFlowNode for s | diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql index c68bd2d274d..984cf74d036 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql +++ b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql @@ -6,6 +6,12 @@ predicate isSafeCheck(DataFlow::GuardNode g, ControlFlowNode node, boolean branc branch = true } +predicate isUnsafeCheck(DataFlow::GuardNode g, ControlFlowNode node, boolean branch) { + g.(CallNode).getNode().getFunc().(Name).getId() in ["is_unsafe", "emulated_is_unsafe"] and + node = g.(CallNode).getAnArg() and + branch = false +} + class CustomSanitizerOverrides extends TestTaintTrackingConfiguration { override predicate isSanitizer(DataFlow::Node node) { exists(Call call | @@ -16,6 +22,8 @@ class CustomSanitizerOverrides extends TestTaintTrackingConfiguration { node.asExpr().(Call).getFunc().(Name).getId() = "emulated_escaping" or node = DataFlow::BarrierGuard::getABarrierNode() + or + node = DataFlow::BarrierGuard::getABarrierNode() } } diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py index a879c3c332c..dc2cc7a5522 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py +++ b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py @@ -22,6 +22,9 @@ def random_choice(): def is_safe(arg): return arg == "safe" +def is_unsafe(arg): + return arg == TAINTED_STRING + def test_basic(): s = TAINTED_STRING @@ -164,6 +167,15 @@ def test_with_return(): ensure_not_tainted(s) # $ SPURIOUS: tainted +def test_with_return_neg(): + s = TAINTED_STRING + + if is_unsafe(s): + return + + ensure_not_tainted(s) + + def test_with_exception(): s = TAINTED_STRING @@ -172,6 +184,14 @@ def test_with_exception(): ensure_not_tainted(s) # $ SPURIOUS: tainted +def test_with_exception_neg(): + s = TAINTED_STRING + + if is_unsafe(s): + raise Exception("unsafe") + + ensure_not_tainted(s) + # Make tests runable test_basic() @@ -182,7 +202,12 @@ test_tricky() test_nesting_not() test_nesting_not_with_and_true() test_with_return() +test_with_return_neg() try: test_with_exception() except: pass +try: + test_with_exception_neg() +except: + pass