Merge branch 'main' into python-port-code-injection

This commit is contained in:
Rasmus Wriedt Larsen
2020-10-14 10:48:38 +02:00
202 changed files with 27977 additions and 3840 deletions

View File

@@ -15,3 +15,4 @@ uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -1,20 +1,33 @@
importModule
| test1.py:1:8:1:12 | ControlFlowNode for ImportExpr | mypkg |
| test1.py:1:8:1:12 | GSSA Variable mypkg | mypkg |
| test2.py:1:6:1:10 | ControlFlowNode for ImportExpr | mypkg |
| test2.py:1:6:1:10 | ControlFlowNode for ImportExpr | mypkg |
| test2.py:1:19:1:21 | GSSA Variable foo | mypkg.foo |
| test2.py:1:24:1:26 | GSSA Variable bar | mypkg.bar |
| test3.py:1:8:1:16 | ControlFlowNode for ImportExpr | mypkg |
| test3.py:1:8:1:16 | ControlFlowNode for ImportExpr | mypkg.foo |
| test3.py:2:8:2:16 | ControlFlowNode for ImportExpr | mypkg |
| test3.py:2:8:2:16 | ControlFlowNode for ImportExpr | mypkg.bar |
| test3.py:2:8:2:16 | GSSA Variable mypkg | mypkg |
| test4.py:1:8:1:16 | ControlFlowNode for ImportExpr | mypkg |
| test4.py:1:8:1:16 | ControlFlowNode for ImportExpr | mypkg.foo |
| test4.py:1:21:1:24 | GSSA Variable _foo | mypkg.foo |
| test4.py:2:8:2:16 | ControlFlowNode for ImportExpr | mypkg |
| test4.py:2:8:2:16 | ControlFlowNode for ImportExpr | mypkg.bar |
| test4.py:2:21:2:24 | GSSA Variable _bar | mypkg.bar |
| test5.py:1:8:1:12 | ControlFlowNode for ImportExpr | mypkg |
| test5.py:1:8:1:12 | GSSA Variable mypkg | mypkg |
| test5.py:9:6:9:10 | ControlFlowNode for ImportExpr | mypkg |
| test5.py:9:26:9:29 | GSSA Variable _bar | mypkg.bar |
| test6.py:1:8:1:12 | ControlFlowNode for ImportExpr | mypkg |
| test6.py:1:8:1:12 | GSSA Variable mypkg | mypkg |
| test6.py:5:8:5:16 | ControlFlowNode for ImportExpr | mypkg |
| test6.py:5:8:5:16 | ControlFlowNode for ImportExpr | mypkg.foo |
| test6.py:5:8:5:16 | GSSA Variable mypkg | mypkg |
| test7.py:1:6:1:10 | ControlFlowNode for ImportExpr | mypkg |
| test7.py:1:19:1:21 | GSSA Variable foo | mypkg.foo |
| test7.py:5:8:5:16 | ControlFlowNode for ImportExpr | mypkg |
| test7.py:5:8:5:16 | ControlFlowNode for ImportExpr | mypkg.foo |
| test7.py:5:8:5:16 | GSSA Variable mypkg | mypkg |
| test7.py:9:6:9:10 | ControlFlowNode for ImportExpr | mypkg |
| test7.py:9:19:9:21 | GSSA Variable foo | mypkg.foo |
importMember
| test2.py:1:19:1:21 | GSSA Variable foo | mypkg | foo |
| test2.py:1:24:1:26 | GSSA Variable bar | mypkg | bar |
| test5.py:9:26:9:29 | GSSA Variable _bar | mypkg | bar |
| test7.py:1:19:1:21 | GSSA Variable foo | mypkg | foo |
| test7.py:9:19:9:21 | GSSA Variable foo | mypkg | foo |

View File

@@ -1,8 +1,4 @@
import python
import experimental.dataflow.DataFlow
query predicate importModule(DataFlow::Node res, string name) { res = DataFlow::importModule(name) }
query predicate importMember(DataFlow::Node res, string moduleName, string memberName) {
res = DataFlow::importMember(moduleName, memberName)
}
query predicate importNode(DataFlow::Node res, string name) { res = DataFlow::importNode(name) }

View File

@@ -137,9 +137,10 @@
| test_string.py:143 | fail | binary_decode_encode | base64.decodestring(..) |
| test_string.py:148 | fail | binary_decode_encode | quopri.encodestring(..) |
| test_string.py:149 | fail | binary_decode_encode | quopri.decodestring(..) |
| test_string.py:158 | ok | test_os_path_join | os.path.join(..) |
| test_string.py:159 | ok | test_os_path_join | os.path.join(..) |
| test_string.py:160 | ok | test_os_path_join | os.path.join(..) |
| test_string.py:161 | ok | test_os_path_join | os.path.join(..) |
| test_string.py:162 | ok | test_os_path_join | ospath_alias.join(..) |
| test_unpacking.py:16 | ok | unpacking | a |
| test_unpacking.py:16 | ok | unpacking | b |
| test_unpacking.py:16 | ok | unpacking | c |

View File

@@ -152,12 +152,14 @@ def binary_decode_encode():
def test_os_path_join():
import os
import os.path as ospath_alias
print("\n# test_os_path_join")
ts = TAINTED_STRING
ensure_tainted(
os.path.join(ts, "foo", "bar"),
os.path.join(ts),
os.path.join("foo", "bar", ts),
ospath_alias.join("foo", "bar", ts),
)

View File

@@ -29,3 +29,73 @@ def test_incompatible_types():
expects_int(x) # $int=field $f+:str=field
x.field = str("Hello") # $f+:int=field $str=field $f+:int $str
expects_string(x) # $f+:int=field $str=field
# Attributes assigned statically to a class
class MyClass: # $tracked=field
field = tracked # $tracked
lookup = MyClass.field # $tracked $tracked=field
instance = MyClass() # $tracked=field
lookup2 = instance.field # $f-:tracked
## Dynamic attribute access
# Via `getattr`/`setattr`
def setattr_immediate_write():
x = SomeClass() # $tracked=foo
setattr(x,"foo", tracked) # $tracked $tracked=foo
y = x.foo # $tracked $tracked=foo
do_stuff(y) # $tracked
def getattr_immediate_read():
x = SomeClass() # $tracked=foo
x.foo = tracked # $tracked $tracked=foo
y = getattr(x,"foo") # $tracked $tracked=foo
do_stuff(y) # $tracked
def setattr_indirect_write():
attr = "foo"
x = SomeClass() # $tracked=foo
setattr(x, attr, tracked) # $tracked $tracked=foo
y = x.foo # $tracked $tracked=foo
do_stuff(y) # $tracked
def getattr_indirect_read():
attr = "foo"
x = SomeClass() # $tracked=foo
x.foo = tracked # $tracked $tracked=foo
y = getattr(x, attr) #$tracked $tracked=foo
do_stuff(y) # $tracked
# Via `__dict__` -- not currently implemented.
def dunder_dict_immediate_write():
x = SomeClass() # $f-:tracked=foo
x.__dict__["foo"] = tracked # $tracked $f-:tracked=foo
y = x.foo # $f-:tracked $f-:tracked=foo
do_stuff(y) # $f-:tracked
def dunder_dict_immediate_read():
x = SomeClass() # $tracked=foo
x.foo = tracked # $tracked $tracked=foo
y = x.__dict__["foo"] # $f-:tracked $tracked=foo
do_stuff(y) # $f-:tracked
def dunder_dict_indirect_write():
attr = "foo"
x = SomeClass() # $f-:tracked=foo
x.__dict__[attr] = tracked # $tracked $f-:tracked=foo
y = x.foo # $f-:tracked $f-:tracked=foo
do_stuff(y) # $f-:tracked
def dunder_dict_indirect_read():
attr = "foo"
x = SomeClass() # $tracked=foo
x.foo = tracked # $tracked $tracked=foo
y = x.__dict__[attr] # $f-:tracked $tracked=foo
do_stuff(y) # $f-:tracked

View File

@@ -0,0 +1,9 @@
from module import attr as attr_ref
x = attr_ref
def fun():
y = attr_ref
# The following should _not_ be a reference to the above module, since we don't actually import it.
z = module

View File

@@ -0,0 +1,10 @@
module_tracker
| import_as_attr.py:1:6:1:11 | ControlFlowNode for ImportExpr |
module_attr_tracker
| import_as_attr.py:0:0:0:0 | ModuleVariableNode for Global Variable attr_ref in Module import_as_attr |
| import_as_attr.py:1:20:1:35 | ControlFlowNode for ImportMember |
| import_as_attr.py:1:28:1:35 | GSSA Variable attr_ref |
| import_as_attr.py:3:1:3:1 | GSSA Variable x |
| import_as_attr.py:3:5:3:12 | ControlFlowNode for attr_ref |
| import_as_attr.py:6:5:6:5 | SSA variable y |
| import_as_attr.py:6:9:6:16 | ControlFlowNode for attr_ref |

View File

@@ -0,0 +1,23 @@
import python
import experimental.dataflow.DataFlow
import experimental.dataflow.TypeTracker
DataFlow::Node module_tracker(TypeTracker t) {
t.start() and
result = DataFlow::importNode("module")
or
exists(TypeTracker t2 | result = module_tracker(t2).track(t2, t))
}
query DataFlow::Node module_tracker() { result = module_tracker(DataFlow::TypeTracker::end()) }
DataFlow::Node module_attr_tracker(TypeTracker t) {
t.startInAttr("attr") and
result = module_tracker()
or
exists(TypeTracker t2 | result = module_attr_tracker(t2).track(t2, t))
}
query DataFlow::Node module_attr_tracker() {
result = module_attr_tracker(DataFlow::TypeTracker::end())
}