Merge branch 'main' into amammad-python-WebAppsConstatntSecretKeys

This commit is contained in:
Rasmus Wriedt Larsen
2023-08-14 11:29:56 +02:00
978 changed files with 48313 additions and 65304 deletions

View File

@@ -65,6 +65,19 @@ def to_inner_scope():
also_x = foo() # $ tracked
print(also_x) # $ tracked
def from_parameter_default():
x_alias = tracked # $tracked
def outer(x=tracked): # $tracked
print(x) # $tracked
def inner():
print(x) # $ tracked
print(x_alias) # $tracked
return x # $tracked
also_x = outer() # $tracked
print(also_x) # $tracked
# ------------------------------------------------------------------------------
# Function decorator
# ------------------------------------------------------------------------------

View File

@@ -292,10 +292,11 @@ module HttpServerHttpResponseTest implements TestSig {
exists(DedicatedResponseTest d | d.isDedicatedFile(file))
) and
(
exists(Http::Server::HttpResponse response |
location = response.getLocation() and
element = response.toString() and
value = prettyNodeForInlineTest(response.getBody()) and
exists(Http::Server::HttpResponse response, DataFlow::Node body |
body = response.getBody() and
location = body.getLocation() and
element = body.toString() and
value = prettyNodeForInlineTest(body) and
tag = "responseBody"
)
or

View File

@@ -3,23 +3,30 @@ edges
| test.py:3:1:3:3 | GSSA Variable BSC | test.py:35:19:35:21 | ControlFlowNode for BSC |
| test.py:3:1:3:3 | GSSA Variable BSC | test.py:66:19:66:21 | ControlFlowNode for BSC |
| test.py:3:7:3:51 | ControlFlowNode for Attribute() | test.py:3:1:3:3 | GSSA Variable BSC |
| test.py:7:19:7:21 | ControlFlowNode for BSC | test.py:8:5:8:15 | ControlFlowNode for blob_client |
| test.py:7:19:7:21 | ControlFlowNode for BSC | test.py:7:19:7:42 | ControlFlowNode for Attribute() |
| test.py:7:19:7:42 | ControlFlowNode for Attribute() | test.py:8:5:8:15 | ControlFlowNode for blob_client |
| test.py:8:5:8:15 | ControlFlowNode for blob_client | test.py:9:5:9:15 | ControlFlowNode for blob_client |
| test.py:9:5:9:15 | ControlFlowNode for blob_client | test.py:9:5:9:15 | [post] ControlFlowNode for blob_client |
| test.py:9:5:9:15 | [post] ControlFlowNode for blob_client | test.py:11:9:11:19 | ControlFlowNode for blob_client |
| test.py:15:27:15:71 | ControlFlowNode for Attribute() | test.py:16:5:16:23 | ControlFlowNode for blob_service_client |
| test.py:16:5:16:23 | ControlFlowNode for blob_service_client | test.py:17:5:17:23 | ControlFlowNode for blob_service_client |
| test.py:17:5:17:23 | ControlFlowNode for blob_service_client | test.py:17:5:17:23 | [post] ControlFlowNode for blob_service_client |
| test.py:17:5:17:23 | [post] ControlFlowNode for blob_service_client | test.py:21:9:21:19 | ControlFlowNode for blob_client |
| test.py:17:5:17:23 | [post] ControlFlowNode for blob_service_client | test.py:19:19:19:37 | ControlFlowNode for blob_service_client |
| test.py:19:19:19:37 | ControlFlowNode for blob_service_client | test.py:19:19:19:58 | ControlFlowNode for Attribute() |
| test.py:19:19:19:58 | ControlFlowNode for Attribute() | test.py:21:9:21:19 | ControlFlowNode for blob_client |
| test.py:25:24:25:66 | ControlFlowNode for Attribute() | test.py:26:5:26:20 | ControlFlowNode for container_client |
| test.py:26:5:26:20 | ControlFlowNode for container_client | test.py:27:5:27:20 | ControlFlowNode for container_client |
| test.py:27:5:27:20 | ControlFlowNode for container_client | test.py:27:5:27:20 | [post] ControlFlowNode for container_client |
| test.py:27:5:27:20 | [post] ControlFlowNode for container_client | test.py:31:9:31:19 | ControlFlowNode for blob_client |
| test.py:35:19:35:21 | ControlFlowNode for BSC | test.py:36:5:36:15 | ControlFlowNode for blob_client |
| test.py:27:5:27:20 | [post] ControlFlowNode for container_client | test.py:29:19:29:34 | ControlFlowNode for container_client |
| test.py:29:19:29:34 | ControlFlowNode for container_client | test.py:29:19:29:55 | ControlFlowNode for Attribute() |
| test.py:29:19:29:55 | ControlFlowNode for Attribute() | test.py:31:9:31:19 | ControlFlowNode for blob_client |
| test.py:35:19:35:21 | ControlFlowNode for BSC | test.py:35:19:35:42 | ControlFlowNode for Attribute() |
| test.py:35:19:35:42 | ControlFlowNode for Attribute() | test.py:36:5:36:15 | ControlFlowNode for blob_client |
| test.py:36:5:36:15 | ControlFlowNode for blob_client | test.py:37:5:37:15 | ControlFlowNode for blob_client |
| test.py:37:5:37:15 | ControlFlowNode for blob_client | test.py:37:5:37:15 | [post] ControlFlowNode for blob_client |
| test.py:37:5:37:15 | [post] ControlFlowNode for blob_client | test.py:43:9:43:19 | ControlFlowNode for blob_client |
| test.py:66:19:66:21 | ControlFlowNode for BSC | test.py:67:5:67:15 | ControlFlowNode for blob_client |
| test.py:66:19:66:21 | ControlFlowNode for BSC | test.py:66:19:66:42 | ControlFlowNode for Attribute() |
| test.py:66:19:66:42 | ControlFlowNode for Attribute() | test.py:67:5:67:15 | ControlFlowNode for blob_client |
| test.py:67:5:67:15 | ControlFlowNode for blob_client | test.py:68:5:68:15 | ControlFlowNode for blob_client |
| test.py:68:5:68:15 | ControlFlowNode for blob_client | test.py:68:5:68:15 | [post] ControlFlowNode for blob_client |
| test.py:68:5:68:15 | [post] ControlFlowNode for blob_client | test.py:69:12:69:22 | ControlFlowNode for blob_client |
@@ -29,6 +36,7 @@ nodes
| test.py:3:1:3:3 | GSSA Variable BSC | semmle.label | GSSA Variable BSC |
| test.py:3:7:3:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:7:19:7:21 | ControlFlowNode for BSC | semmle.label | ControlFlowNode for BSC |
| test.py:7:19:7:42 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:8:5:8:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client |
| test.py:9:5:9:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client |
| test.py:9:5:9:15 | [post] ControlFlowNode for blob_client | semmle.label | [post] ControlFlowNode for blob_client |
@@ -37,18 +45,24 @@ nodes
| test.py:16:5:16:23 | ControlFlowNode for blob_service_client | semmle.label | ControlFlowNode for blob_service_client |
| test.py:17:5:17:23 | ControlFlowNode for blob_service_client | semmle.label | ControlFlowNode for blob_service_client |
| test.py:17:5:17:23 | [post] ControlFlowNode for blob_service_client | semmle.label | [post] ControlFlowNode for blob_service_client |
| test.py:19:19:19:37 | ControlFlowNode for blob_service_client | semmle.label | ControlFlowNode for blob_service_client |
| test.py:19:19:19:58 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:21:9:21:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client |
| test.py:25:24:25:66 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:26:5:26:20 | ControlFlowNode for container_client | semmle.label | ControlFlowNode for container_client |
| test.py:27:5:27:20 | ControlFlowNode for container_client | semmle.label | ControlFlowNode for container_client |
| test.py:27:5:27:20 | [post] ControlFlowNode for container_client | semmle.label | [post] ControlFlowNode for container_client |
| test.py:29:19:29:34 | ControlFlowNode for container_client | semmle.label | ControlFlowNode for container_client |
| test.py:29:19:29:55 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:31:9:31:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client |
| test.py:35:19:35:21 | ControlFlowNode for BSC | semmle.label | ControlFlowNode for BSC |
| test.py:35:19:35:42 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:36:5:36:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client |
| test.py:37:5:37:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client |
| test.py:37:5:37:15 | [post] ControlFlowNode for blob_client | semmle.label | [post] ControlFlowNode for blob_client |
| test.py:43:9:43:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client |
| test.py:66:19:66:21 | ControlFlowNode for BSC | semmle.label | ControlFlowNode for BSC |
| test.py:66:19:66:42 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:67:5:67:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client |
| test.py:68:5:68:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client |
| test.py:68:5:68:15 | [post] ControlFlowNode for blob_client | semmle.label | [post] ControlFlowNode for blob_client |

View File

@@ -1,2 +1,19 @@
import experimental.meta.InlineTaintTest
import MakeInlineTaintTest<TestTaintTrackingConfig>
predicate isSafe(DataFlow::GuardNode g, ControlFlowNode node, boolean branch) {
g.(CallNode).getFunction().(NameNode).getId() = "is_safe" and
node = g.(CallNode).getArg(_) and
branch = true
}
module CustomSanitizerOverridesConfig implements DataFlow::ConfigSig {
predicate isSource = TestTaintTrackingConfig::isSource/1;
predicate isSink = TestTaintTrackingConfig::isSink/1;
predicate isBarrier(DataFlow::Node node) {
node = DataFlow::BarrierGuard<isSafe/3>::getABarrierNode()
}
}
import MakeInlineTaintTest<CustomSanitizerOverridesConfig>

View File

@@ -33,3 +33,5 @@ async def test():
assert context.verify_mode == ssl.VerifyMode.CERT_NONE
s.get("url", ssl=context) # $ clientRequestUrlPart="url" MISSING: clientRequestCertValidationDisabled
s.ws_connect("url") # $ clientRequestUrlPart="url"

View File

@@ -23,6 +23,9 @@ async def html_text(request): # $ requestHandler
async def html_body(request): # $ requestHandler
return web.Response(body=b"foo", content_type="text/html") # $ HttpResponse mimetype=text/html responseBody=b"foo"
@routes.get("/html_body_header") # $ routeSetup="/html_body_header"
async def html_body_header(request): # $ requestHandler
return web.Response(headers={"content-type": "text/html"}, text="foo") # $ HttpResponse mimetype=text/html responseBody="foo"
@routes.get("/html_body_set_later") # $ routeSetup="/html_body_set_later"
async def html_body_set_later(request): # $ requestHandler
@@ -65,6 +68,26 @@ async def redirect_302(request): # $ requestHandler
else:
raise web.HTTPFound(location="/logout") # $ HttpResponse HttpRedirectResponse mimetype=application/octet-stream redirectLocation="/logout"
@routes.get("/file_response") # $ routeSetup="/file_response"
async def file_response(request): # $ requestHandler
filename = "foo.txt"
resp = web.FileResponse(filename) # $ HttpResponse mimetype=application/octet-stream getAPathArgument=filename
resp = web.FileResponse(path=filename) # $ HttpResponse mimetype=application/octet-stream getAPathArgument=filename
return resp
@routes.get("/streaming_response") # $ routeSetup="/streaming_response"
async def streaming_response(request): # $ requestHandler
resp = web.StreamResponse() # $ HttpResponse mimetype=application/octet-stream
await resp.prepare(request)
await resp.write(b"foo") # $ responseBody=b"foo"
await resp.write(data=b"bar") # $ responseBody=b"bar"
await resp.write_eof(b"baz") # $ responseBody=b"baz"
return resp
################################################################################
# Cookies
################################################################################

View File

@@ -142,10 +142,36 @@ class TaintTestClass(web.View):
self.request.url # $ tainted
)
# not a request handler, and not called, but since we have type-annotation, should be a
# remote-flow-source.
async def test_source_from_type_annotation(request: web.Request):
# picking out just a few of the tests from `test_taint` above, to show that we have
# the same taint-steps :)
ensure_tainted(
request, # $ tainted
request.url, # $ tainted
await request.content.read(), # $ tainted
)
# Test that since we can reach the `request` object in the helper function, we don't
# introduce a new remote-flow-source, but instead use the one from the caller. (which is
# checked to not be tainted)
async def test_sanitizer(request): # $ requestHandler
ensure_tainted(request, request.url, await request.content.read()) # $ tainted
if (is_safe(request)):
ensure_not_tainted(request, request.url, await request.content.read())
test_safe_helper_function_no_route_with_type(request)
async def test_safe_helper_function_no_route_with_type(request: web.Request):
ensure_not_tainted(request, request.url, await request.content.read()) # $ SPURIOUS: tainted
app = web.Application()
app.router.add_get(r"/test_taint/{name}/{number:\d+}", test_taint) # $ routeSetup="/test_taint/{name}/{number:\d+}"
app.router.add_view(r"/test_taint_class", TaintTestClass) # $ routeSetup="/test_taint_class"
app.router.add_view(r"/test_sanitizer", test_sanitizer) # $ routeSetup="/test_sanitizer"
if __name__ == "__main__":

View File

@@ -11,6 +11,11 @@ taintFlow
| test.py:83:50:83:60 | ControlFlowNode for getSource() | test.py:83:8:83:61 | ControlFlowNode for Attribute() |
| test.py:86:49:86:59 | ControlFlowNode for getSource() | test.py:86:8:86:60 | ControlFlowNode for Attribute() |
| test.py:87:56:87:66 | ControlFlowNode for getSource() | test.py:87:8:87:67 | ControlFlowNode for Attribute() |
| test.py:114:19:114:29 | ControlFlowNode for getSource() | test.py:114:19:114:29 | ControlFlowNode for getSource() |
| test.py:115:20:115:30 | ControlFlowNode for getSource() | test.py:115:20:115:30 | ControlFlowNode for getSource() |
| test.py:116:31:116:41 | ControlFlowNode for getSource() | test.py:116:31:116:41 | ControlFlowNode for getSource() |
| test.py:117:31:117:41 | ControlFlowNode for getSource() | test.py:117:31:117:41 | ControlFlowNode for getSource() |
| test.py:118:35:118:45 | ControlFlowNode for getSource() | test.py:118:35:118:45 | ControlFlowNode for getSource() |
isSink
| test.py:4:8:4:8 | ControlFlowNode for x | test-sink |
| test.py:7:17:7:17 | ControlFlowNode for x | test-sink |
@@ -50,6 +55,11 @@ isSink
| test.py:91:21:91:23 | ControlFlowNode for one | test-sink |
| test.py:91:30:91:32 | ControlFlowNode for two | test-sink |
| test.py:98:6:98:9 | ControlFlowNode for baz2 | test-sink |
| test.py:114:19:114:29 | ControlFlowNode for getSource() | test-sink |
| test.py:115:20:115:30 | ControlFlowNode for getSource() | test-sink |
| test.py:116:31:116:41 | ControlFlowNode for getSource() | test-sink |
| test.py:117:31:117:41 | ControlFlowNode for getSource() | test-sink |
| test.py:118:35:118:45 | ControlFlowNode for getSource() | test-sink |
isSource
| test.py:3:5:3:15 | ControlFlowNode for getSource() | test-source |
| test.py:9:8:9:14 | ControlFlowNode for alias() | test-source |
@@ -89,6 +99,12 @@ isSource
| test.py:104:32:104:37 | ControlFlowNode for param2 | test-source |
| test.py:107:24:107:28 | ControlFlowNode for name1 | test-source |
| test.py:107:31:107:35 | ControlFlowNode for name2 | test-source |
| test.py:114:19:114:29 | ControlFlowNode for getSource() | test-source |
| test.py:115:20:115:30 | ControlFlowNode for getSource() | test-source |
| test.py:116:31:116:41 | ControlFlowNode for getSource() | test-source |
| test.py:117:31:117:41 | ControlFlowNode for getSource() | test-source |
| test.py:118:35:118:45 | ControlFlowNode for getSource() | test-source |
| test.py:119:20:119:30 | ControlFlowNode for getSource() | test-source |
syntaxErrors
| Member[foo |
| Member[foo] .Member[bar] |

View File

@@ -60,7 +60,7 @@ class SubClass (ArgPos.MyClass):
def foo(self, arg, named=2, otherName=3):
pass
def secondAndAfter(self, arg1, arg2, arg3, arg4, arg5):
def secondAndAfter(self, arg1, arg2, arg3, arg4, arg5):
pass
ArgPos.anyParam(arg1, arg2, name=namedThing)
@@ -72,7 +72,7 @@ mySink(Steps.preserveTaint(getSource())) # FLOW
mySink(Steps.preserveTaint("safe", getSource())) # NO FLOW
Steps.taintIntoCallback(
getSource(),
getSource(),
lambda x: mySink(x), # FLOW
lambda y: mySink(y), # FLOW
lambda z: mySink(z) # NO FLOW
@@ -106,3 +106,14 @@ class OtherSubClass (ArgPos.MyClass):
def anyNamed(self, name1, name2=2): # Parameter[any-named] matches all non-self named parameters
pass
import testlib as testlib
import testlib.nestedlib as testlib2
import otherlib as otherlib
testlib.fuzzyCall(getSource()) # NOT OK
testlib2.fuzzyCall(getSource()) # NOT OK
testlib.foo.bar.baz.fuzzyCall(getSource()) # NOT OK
testlib.foo().bar().fuzzyCall(getSource()) # NOT OK
testlib.foo(lambda x: x.fuzzyCall(getSource())) # NOT OK
otherlib.fuzzyCall(getSource()) # OK

View File

@@ -51,6 +51,8 @@ class Sinks extends ModelInput::SinkModelCsv {
// testing package syntax
"foo1.bar;Member[baz1].Argument[any];test-sink", //
"foo2;Member[bar].Member[baz2].Argument[any];test-sink", //
// testing fuzzy
"testlib;Fuzzy.Member[fuzzyCall].Argument[0];test-sink", //
]
}
}

View File

@@ -0,0 +1,4 @@
| test.py:3:5:3:9 | ControlFlowNode for fail5 | test.py:3:1:3:13 | ControlFlowNode for FunctionExpr |
| test.py:4:5:4:8 | ControlFlowNode for Tuple | test.py:4:12:4:12 | ControlFlowNode for t |
| test.py:7:5:7:26 | ControlFlowNode for default_value_in_param | test.py:7:1:7:33 | ControlFlowNode for FunctionExpr |
| test.py:7:28:7:28 | ControlFlowNode for x | test.py:7:30:7:31 | ControlFlowNode for IntegerLiteral |

View File

@@ -0,0 +1,4 @@
import python
from DefinitionNode d
select d, d.getValue()

View File

@@ -1,4 +1,6 @@
| 3 | 5 | ControlFlowNode for fail5 |
| 4 | 5 | ControlFlowNode for Tuple |
| 4 | 5 | ControlFlowNode for x |
| 4 | 8 | ControlFlowNode for y |
| 4 | 8 | ControlFlowNode for y |
| 7 | 5 | ControlFlowNode for default_value_in_param |
| 7 | 28 | ControlFlowNode for x |

View File

@@ -3,3 +3,6 @@
def fail5(t):
x, y = t
return x
def default_value_in_param(x=42):
print(x)