Merge branch 'main' into python-dataflow/flow-summaries-from-scratch

This commit is contained in:
yoff
2022-08-10 10:57:59 +02:00
committed by GitHub
1004 changed files with 60156 additions and 68392 deletions

View File

@@ -50,7 +50,7 @@ def test_non_eq2():
if not ts == "safe":
ensure_tainted(ts) # $ tainted
else:
ensure_not_tainted(ts) # $ SPURIOUS: tainted
ensure_not_tainted(ts)
def test_in_list():
@@ -157,7 +157,7 @@ def test_not_in2():
if not ts in ["safe", "also_safe"]:
ensure_tainted(ts) # $ tainted
else:
ensure_not_tainted(ts) # $ SPURIOUS: tainted
ensure_not_tainted(ts)
def is_safe(x):

View File

@@ -6,12 +6,20 @@ 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:40:28:40: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:111:28:111:28 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:130:28:130:28 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:137:28:137: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:167:24:167:24 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:176:24:176:24 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:185:24:185: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 |

View File

@@ -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<isSafeCheck/3>::getABarrierNode()
or
node = DataFlow::BarrierGuard<isUnsafeCheck/3>::getABarrierNode()
}
}

View File

@@ -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
@@ -34,7 +37,7 @@ def test_basic():
if not is_safe(s):
ensure_tainted(s) # $ tainted
else:
ensure_not_tainted(s) # $ SPURIOUS: tainted
ensure_not_tainted(s)
def test_if_in_depth():
@@ -105,7 +108,7 @@ def test_and():
ensure_tainted(s) # $ tainted
else:
# cannot be tainted
ensure_not_tainted(s) # $ SPURIOUS: tainted
ensure_not_tainted(s)
def test_tricky():
@@ -124,14 +127,14 @@ def test_nesting_not():
s = TAINTED_STRING
if not(not(is_safe(s))):
ensure_not_tainted(s) # $ SPURIOUS: tainted
ensure_not_tainted(s)
else:
ensure_tainted(s) # $ tainted
if not(not(not(is_safe(s)))):
ensure_tainted(s) # $ tainted
else:
ensure_not_tainted(s) # $ SPURIOUS: tainted
ensure_not_tainted(s)
# Adding `and True` makes the sanitizer trigger when it would otherwise not. See output in
@@ -161,7 +164,16 @@ def test_with_return():
if not is_safe(s):
return
ensure_not_tainted(s) # $ SPURIOUS: tainted
ensure_not_tainted(s)
def test_with_return_neg():
s = TAINTED_STRING
if is_unsafe(s):
return
ensure_not_tainted(s)
def test_with_exception():
@@ -170,7 +182,15 @@ def test_with_exception():
if not is_safe(s):
raise Exception("unsafe")
ensure_not_tainted(s) # $ SPURIOUS: tainted
ensure_not_tainted(s)
def test_with_exception_neg():
s = TAINTED_STRING
if is_unsafe(s):
raise Exception("unsafe")
ensure_not_tainted(s)
# Make tests runable
@@ -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

View File

@@ -65,6 +65,9 @@ def to_inner_scope():
also_x = foo() # $ MISSING: tracked
print(also_x) # $ MISSING: tracked
# ------------------------------------------------------------------------------
# Function decorator
# ------------------------------------------------------------------------------
def my_decorator(func):
# This part doesn't make any sense in a normal decorator, but just shows how we
@@ -135,7 +138,7 @@ class Bar(Foo):
def track_self(self): # $ tracked_self
self.meth1() # $ tracked_self
super().meth2()
super(Bar, self).foo3() # $ tracked_self
super(Bar, self).meth3() # $ tracked_self
# ------------------------------------------------------------------------------
# Tracking of attribute lookup after "long" import chain

View File

@@ -16,4 +16,19 @@ def internal():
def my_internal_method(self): #$ def=moduleImport("pflask").getMember("views").getMember("View").getASubclass().getMember("my_internal_method")
pass
int_instance = IntMyView() #$ use=moduleImport("pflask").getMember("views").getMember("View").getASubclass().getReturn()
int_instance = IntMyView() #$ use=moduleImport("pflask").getMember("views").getMember("View").getASubclass().getReturn()
# ------------------------------------------------------------------------------
# Class decorator
# ------------------------------------------------------------------------------
def my_class_decorator(cls):
print("dummy decorator")
return cls
@my_class_decorator
class MyViewWithDecorator(View): #$ use=moduleImport("flask").getMember("views").getMember("View").getASubclass()
pass
class SubclassFromDecorated(MyViewWithDecorator): #$ use=moduleImport("flask").getMember("views").getMember("View").getASubclass().getASubclass()
pass

View File

@@ -7,8 +7,6 @@ edges
| tarslip.py:40:7:40:39 | ControlFlowNode for Attribute() | tarslip.py:41:24:41:26 | ControlFlowNode for tar |
| tarslip.py:56:7:56:39 | ControlFlowNode for Attribute() | tarslip.py:57:5:57:9 | GSSA Variable entry |
| tarslip.py:57:5:57:9 | GSSA Variable entry | tarslip.py:59:21:59:25 | ControlFlowNode for entry |
| tarslip.py:79:7:79:39 | ControlFlowNode for Attribute() | tarslip.py:80:5:80:9 | GSSA Variable entry |
| tarslip.py:80:5:80:9 | GSSA Variable entry | tarslip.py:82:21:82:25 | ControlFlowNode for entry |
nodes
| tarslip.py:12:7:12:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| tarslip.py:13:1:13:3 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar |
@@ -23,9 +21,6 @@ nodes
| tarslip.py:56:7:56:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| tarslip.py:57:5:57:9 | GSSA Variable entry | semmle.label | GSSA Variable entry |
| tarslip.py:59:21:59:25 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry |
| tarslip.py:79:7:79:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| tarslip.py:80:5:80:9 | GSSA Variable entry | semmle.label | GSSA Variable entry |
| tarslip.py:82:21:82:25 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry |
subpaths
#select
| tarslip.py:13:1:13:3 | ControlFlowNode for tar | tarslip.py:12:7:12:39 | ControlFlowNode for Attribute() | tarslip.py:13:1:13:3 | ControlFlowNode for tar | Extraction of tarfile from $@ | tarslip.py:12:7:12:39 | ControlFlowNode for Attribute() | a potentially untrusted source |
@@ -33,4 +28,3 @@ subpaths
| tarslip.py:37:17:37:21 | ControlFlowNode for entry | tarslip.py:33:7:33:39 | ControlFlowNode for Attribute() | tarslip.py:37:17:37:21 | ControlFlowNode for entry | Extraction of tarfile from $@ | tarslip.py:33:7:33:39 | ControlFlowNode for Attribute() | a potentially untrusted source |
| tarslip.py:41:24:41:26 | ControlFlowNode for tar | tarslip.py:40:7:40:39 | ControlFlowNode for Attribute() | tarslip.py:41:24:41:26 | ControlFlowNode for tar | Extraction of tarfile from $@ | tarslip.py:40:7:40:39 | ControlFlowNode for Attribute() | a potentially untrusted source |
| tarslip.py:59:21:59:25 | ControlFlowNode for entry | tarslip.py:56:7:56:39 | ControlFlowNode for Attribute() | tarslip.py:59:21:59:25 | ControlFlowNode for entry | Extraction of tarfile from $@ | tarslip.py:56:7:56:39 | ControlFlowNode for Attribute() | a potentially untrusted source |
| tarslip.py:82:21:82:25 | ControlFlowNode for entry | tarslip.py:79:7:79:39 | ControlFlowNode for Attribute() | tarslip.py:82:21:82:25 | ControlFlowNode for entry | Extraction of tarfile from $@ | tarslip.py:79:7:79:39 | ControlFlowNode for Attribute() | a potentially untrusted source |