Merge branch 'main' into py-restframework

This commit is contained in:
Mathew Payne
2023-10-20 11:39:07 +01:00
committed by GitHub
1369 changed files with 93501 additions and 15520 deletions

View File

@@ -33,10 +33,10 @@ identityLocalStep
| test.py:167:13:167:18 | ControlFlowNode for SOURCE | Node steps to itself |
| test.py:216:10:216:15 | ControlFlowNode for SOURCE | Node steps to itself |
| test.py:242:9:242:12 | ControlFlowNode for SINK | Node steps to itself |
| test.py:669:9:669:12 | ControlFlowNode for SINK | Node steps to itself |
| test.py:670:9:670:14 | ControlFlowNode for SINK_F | Node steps to itself |
| test.py:678:9:678:12 | ControlFlowNode for SINK | Node steps to itself |
| test.py:686:9:686:12 | ControlFlowNode for SINK | Node steps to itself |
| test.py:692:5:692:8 | ControlFlowNode for SINK | Node steps to itself |
| test.py:673:9:673:12 | ControlFlowNode for SINK | Node steps to itself |
| test.py:674:9:674:14 | ControlFlowNode for SINK_F | Node steps to itself |
| test.py:682:9:682:12 | ControlFlowNode for SINK | Node steps to itself |
| test.py:690:9:690:12 | ControlFlowNode for SINK | Node steps to itself |
| test.py:696:5:696:8 | ControlFlowNode for SINK | Node steps to itself |
missingArgumentCall
multipleArgumentCall

View File

@@ -435,10 +435,14 @@ def test_and(x = True):
# 6.12. Assignment expressions
def test_assignment_expression():
def test_assignment_expression_flow_lhs():
x = NONSOURCE
SINK(x := SOURCE) #$ MISSING:flow="SOURCE -> x"
if x := SOURCE:
SINK(x) #$ flow="SOURCE, l:-1 -> x"
def test_assignment_expression_flow_out():
x = NONSOURCE
SINK(x := SOURCE) #$ flow="SOURCE -> AssignExpr"
# 6.13. Conditional expressions
def test_conditional_true():
@@ -460,13 +464,13 @@ def test_conditional_false_guards():
# Condition is evaluated first, so x is SOURCE once chosen
def test_conditional_evaluation_true():
x = NONSOURCE
SINK(x if (SOURCE == (x := SOURCE)) else NONSOURCE) #$ MISSING:flow="SOURCE -> IfExp"
SINK(x if (SOURCE == (x := SOURCE)) else NONSOURCE) #$ flow="SOURCE -> IfExp"
# Condition is evaluated first, so x is SOURCE once chosen
def test_conditional_evaluation_false():
x = NONSOURCE
SINK(NONSOURCE if (NONSOURCE == (x := SOURCE)) else x) #$ MISSING:flow="SOURCE -> IfExp"
SINK(NONSOURCE if (NONSOURCE == (x := SOURCE)) else x) #$ flow="SOURCE -> IfExp"
# 6.14. Lambdas

View File

@@ -195,3 +195,42 @@ class MyClass(object):
def with_global_modifier(self):
global some_value
print(some_value) # $ tracked
# ------------------------------------------------------------------------------
# yield
# ------------------------------------------------------------------------------
def yielding_function():
x = tracked # $ tracked
yield x # $ tracked
def test_yield():
for x in yielding_function(): # $ MISSING: tracked
print(x) # $ MISSING: tracked
gen = yielding_function()
y = next(gen) # $ MISSING: tracked
print(y) # $ MISSING: tracked
# see https://docs.python.org/3.11/library/contextlib.html#contextlib.contextmanager
from contextlib import contextmanager
import contextlib
@contextmanager
def managed_resource():
x = tracked # $ tracked
yield x # $ tracked
def test_context_manager():
with managed_resource() as x: # $ tracked
print(x) # $ tracked
@contextlib.contextmanager
def managed_resource2():
x = tracked # $ tracked
yield x # $ tracked
def test_context_manager2():
with managed_resource2() as x: # $ tracked
print(x) # $ tracked

View File

@@ -32,6 +32,12 @@ edges
| TarSlipImprov.py:141:6:141:29 | ControlFlowNode for Attribute() | TarSlipImprov.py:141:34:141:36 | GSSA Variable tar |
| TarSlipImprov.py:141:34:141:36 | GSSA Variable tar | TarSlipImprov.py:142:9:142:13 | GSSA Variable entry |
| TarSlipImprov.py:142:9:142:13 | GSSA Variable entry | TarSlipImprov.py:143:36:143:40 | ControlFlowNode for entry |
| TarSlipImprov.py:151:14:151:50 | ControlFlowNode for closing() | TarSlipImprov.py:151:55:151:56 | SSA variable tf |
| TarSlipImprov.py:151:22:151:49 | ControlFlowNode for Attribute() | TarSlipImprov.py:151:14:151:50 | ControlFlowNode for closing() |
| TarSlipImprov.py:151:55:151:56 | SSA variable tf | TarSlipImprov.py:152:19:152:20 | ControlFlowNode for tf |
| TarSlipImprov.py:152:19:152:20 | ControlFlowNode for tf | TarSlipImprov.py:157:18:157:40 | ControlFlowNode for py2_tarxz() |
| TarSlipImprov.py:157:9:157:14 | SSA variable tar_cm | TarSlipImprov.py:162:20:162:23 | SSA variable tarc |
| TarSlipImprov.py:157:18:157:40 | ControlFlowNode for py2_tarxz() | TarSlipImprov.py:157:9:157:14 | SSA variable tar_cm |
| TarSlipImprov.py:159:9:159:14 | SSA variable tar_cm | TarSlipImprov.py:162:20:162:23 | SSA variable tarc |
| TarSlipImprov.py:159:18:159:52 | ControlFlowNode for closing() | TarSlipImprov.py:159:9:159:14 | SSA variable tar_cm |
| TarSlipImprov.py:159:26:159:51 | ControlFlowNode for Attribute() | TarSlipImprov.py:159:18:159:52 | ControlFlowNode for closing() |
@@ -122,6 +128,12 @@ nodes
| TarSlipImprov.py:141:34:141:36 | GSSA Variable tar | semmle.label | GSSA Variable tar |
| TarSlipImprov.py:142:9:142:13 | GSSA Variable entry | semmle.label | GSSA Variable entry |
| TarSlipImprov.py:143:36:143:40 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry |
| TarSlipImprov.py:151:14:151:50 | ControlFlowNode for closing() | semmle.label | ControlFlowNode for closing() |
| TarSlipImprov.py:151:22:151:49 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| TarSlipImprov.py:151:55:151:56 | SSA variable tf | semmle.label | SSA variable tf |
| TarSlipImprov.py:152:19:152:20 | ControlFlowNode for tf | semmle.label | ControlFlowNode for tf |
| TarSlipImprov.py:157:9:157:14 | SSA variable tar_cm | semmle.label | SSA variable tar_cm |
| TarSlipImprov.py:157:18:157:40 | ControlFlowNode for py2_tarxz() | semmle.label | ControlFlowNode for py2_tarxz() |
| TarSlipImprov.py:159:9:159:14 | SSA variable tar_cm | semmle.label | SSA variable tar_cm |
| TarSlipImprov.py:159:18:159:52 | ControlFlowNode for closing() | semmle.label | ControlFlowNode for closing() |
| TarSlipImprov.py:159:26:159:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
@@ -199,6 +211,7 @@ subpaths
| TarSlipImprov.py:130:5:130:7 | ControlFlowNode for tar | TarSlipImprov.py:129:6:129:26 | ControlFlowNode for Attribute() | TarSlipImprov.py:130:5:130:7 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:129:6:129:26 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:130:5:130:7 | ControlFlowNode for tar | ControlFlowNode for tar |
| TarSlipImprov.py:134:1:134:3 | ControlFlowNode for tar | TarSlipImprov.py:133:7:133:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:134:1:134:3 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:133:7:133:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:134:1:134:3 | ControlFlowNode for tar | ControlFlowNode for tar |
| TarSlipImprov.py:143:36:143:40 | ControlFlowNode for entry | TarSlipImprov.py:141:6:141:29 | ControlFlowNode for Attribute() | TarSlipImprov.py:143:36:143:40 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:141:6:141:29 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:143:36:143:40 | ControlFlowNode for entry | ControlFlowNode for entry |
| TarSlipImprov.py:169:9:169:12 | ControlFlowNode for tarc | TarSlipImprov.py:151:22:151:49 | ControlFlowNode for Attribute() | TarSlipImprov.py:169:9:169:12 | ControlFlowNode for tarc | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:151:22:151:49 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:169:9:169:12 | ControlFlowNode for tarc | ControlFlowNode for tarc |
| TarSlipImprov.py:169:9:169:12 | ControlFlowNode for tarc | TarSlipImprov.py:159:26:159:51 | ControlFlowNode for Attribute() | TarSlipImprov.py:169:9:169:12 | ControlFlowNode for tarc | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:159:26:159:51 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:169:9:169:12 | ControlFlowNode for tarc | ControlFlowNode for tarc |
| TarSlipImprov.py:178:36:178:40 | ControlFlowNode for entry | TarSlipImprov.py:176:6:176:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:178:36:178:40 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:176:6:176:31 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:178:36:178:40 | ControlFlowNode for entry | ControlFlowNode for entry |
| TarSlipImprov.py:184:21:184:25 | ControlFlowNode for entry | TarSlipImprov.py:182:6:182:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:184:21:184:25 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:182:6:182:31 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:184:21:184:25 | ControlFlowNode for entry | ControlFlowNode for entry |

View File

@@ -2,9 +2,11 @@
from unknown import * #$ use=moduleImport("unknown")
# Currently missing, as we do not consider `hello` to be a `LocalSourceNode`, since it has flow
# going into it from its corresponding `GlobalSsaVariable`.
hello() #$ MISSING: use=moduleImport("unknown").getMember("hello").getReturn()
# This used to be missing, as we did not consider `hello` to be a `LocalSourceNode`,
# since it has flow going into it from its corresponding `GlobalSsaVariable`.
hello() #$ use=moduleImport("unknown").getMember("hello").getReturn()
print(const_from_unknown) #$ use=moduleImport("unknown").getMember("const_from_unknown")
# We don't want our analysis to think that either `non_module_member` or `outer_bar` can
# come from `from unknown import *`

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -0,0 +1,2 @@
import python
import experimental.meta.ConceptsTest

View File

@@ -0,0 +1,4 @@
import joblib
joblib.load(file_) # $ decodeInput=file_ decodeOutput=joblib.load(..) decodeFormat=joblib decodeMayExecuteInput
joblib.load(filename=file_) # $ decodeInput=file_ decodeOutput=joblib.load(..) decodeFormat=joblib decodeMayExecuteInput

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -0,0 +1,2 @@
import python
import experimental.meta.ConceptsTest

View File

@@ -0,0 +1,6 @@
import numpy
numpy.load(file_) # $ decodeInput=file_ decodeOutput=numpy.load(..) decodeFormat=numpy
numpy.load(filename=file_) # $ decodeInput=file_ decodeOutput=numpy.load(..) decodeFormat=numpy
numpy.load(file_, allow_pickle=True) # $ decodeInput=file_ decodeOutput=numpy.load(..) decodeFormat=numpy decodeFormat=pickle decodeMayExecuteInput
numpy.load(file_, None, True) # $ decodeInput=file_ decodeOutput=numpy.load(..) decodeFormat=numpy decodeFormat=pickle decodeMayExecuteInput

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -0,0 +1,2 @@
import python
import experimental.meta.ConceptsTest

View File

@@ -0,0 +1,4 @@
import pandas
pandas.read_pickle(file_) # $ decodeInput=file_ decodeOutput=pandas.read_pickle(..) decodeFormat=pickle decodeMayExecuteInput
pandas.read_pickle(filepath_or_buffer=file_) # $ decodeInput=file_ decodeOutput=pandas.read_pickle(..) decodeFormat=pickle decodeMayExecuteInput

View File

@@ -8,3 +8,4 @@
| test.py:25:32:25:34 | 7-F | Suspicious character range that is equivalent to [7-9:;<=>?@A-F]. |
| test.py:27:36:27:38 | 0-9 | Suspicious character range that overlaps with \\d in the same character class. |
| test.py:29:39:29:41 | .-? | Suspicious character range that overlaps with \\w in the same character class, and is equivalent to [.\\/0-9:;<=>?]. |
| test.py:31:30:31:32 | \ufffd-\ufffd | Suspicious character range that overlaps with \\ufffd-\\ufffd in the same character class. |

View File

@@ -27,3 +27,5 @@ numberToLetter = re.compile(r'[7-F]') # NOT OK
overlapsWithClass1 = re.compile(r'[0-9\d]') # NOT OK
overlapsWithClass2 = re.compile(r'[\w,.-?:*+]') # NOT OK
unicodeStuff = re.compile('[\U0001D173-\U0001D17A\U000E0020-\U000E007F\U000e0001]') # NOT OK

View File

@@ -5,6 +5,7 @@ edges
| unsafe_deserialization.py:14:5:14:11 | SSA variable payload | unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload |
| unsafe_deserialization.py:14:5:14:11 | SSA variable payload | unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload |
| unsafe_deserialization.py:14:5:14:11 | SSA variable payload | unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload |
| unsafe_deserialization.py:14:5:14:11 | SSA variable payload | unsafe_deserialization.py:24:24:24:30 | ControlFlowNode for payload |
| unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute |
| unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:14:15:14:41 | ControlFlowNode for Attribute() |
| unsafe_deserialization.py:14:15:14:41 | ControlFlowNode for Attribute() | unsafe_deserialization.py:14:5:14:11 | SSA variable payload |
@@ -19,9 +20,11 @@ nodes
| unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload |
| unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload |
| unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload |
| unsafe_deserialization.py:24:24:24:30 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload |
subpaths
#select
| unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value |
| unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value |
| unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value |
| unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value |
| unsafe_deserialization.py:24:24:24:30 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:24:24:24:30 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value |

View File

@@ -19,3 +19,6 @@ def hello():
import dill
dill.loads(payload) # NOT OK
import pandas
pandas.read_pickle(payload) # NOT OK