mirror of
https://github.com/github/codeql.git
synced 2026-05-02 12:15:17 +02:00
Merge pull request #6155 from RasmusWL/port-cleartext-queries
Python: Port cleartext queries
This commit is contained in:
@@ -93,6 +93,23 @@ class EncodingTest extends InlineExpectationsTest {
|
||||
}
|
||||
}
|
||||
|
||||
class LoggingTest extends InlineExpectationsTest {
|
||||
LoggingTest() { this = "LoggingTest" }
|
||||
|
||||
override string getARelevantTag() { result in ["loggingInput"] }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(location.getFile().getRelativePath()) and
|
||||
exists(Logging logging, DataFlow::Node data |
|
||||
location = data.getLocation() and
|
||||
element = data.toString() and
|
||||
value = prettyNodeForInlineTest(data) and
|
||||
data = logging.getAnInput() and
|
||||
tag = "loggingInput"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class CodeExecutionTest extends InlineExpectationsTest {
|
||||
CodeExecutionTest() { this = "CodeExecutionTest" }
|
||||
|
||||
@@ -284,6 +301,38 @@ class HttpServerHttpRedirectResponseTest extends InlineExpectationsTest {
|
||||
}
|
||||
}
|
||||
|
||||
class HttpServerCookieWriteTest extends InlineExpectationsTest {
|
||||
HttpServerCookieWriteTest() { this = "HttpServerCookieWriteTest" }
|
||||
|
||||
override string getARelevantTag() {
|
||||
result in ["CookieWrite", "CookieRawHeader", "CookieName", "CookieValue"]
|
||||
}
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(location.getFile().getRelativePath()) and
|
||||
exists(HTTP::Server::CookieWrite cookieWrite |
|
||||
location = cookieWrite.getLocation() and
|
||||
(
|
||||
element = cookieWrite.toString() and
|
||||
value = "" and
|
||||
tag = "CookieWrite"
|
||||
or
|
||||
element = cookieWrite.toString() and
|
||||
value = prettyNodeForInlineTest(cookieWrite.getHeaderArg()) and
|
||||
tag = "CookieRawHeader"
|
||||
or
|
||||
element = cookieWrite.toString() and
|
||||
value = prettyNodeForInlineTest(cookieWrite.getNameArg()) and
|
||||
tag = "CookieName"
|
||||
or
|
||||
element = cookieWrite.toString() and
|
||||
value = prettyNodeForInlineTest(cookieWrite.getValueArg()) and
|
||||
tag = "CookieValue"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class FileSystemAccessTest extends InlineExpectationsTest {
|
||||
FileSystemAccessTest() { this = "FileSystemAccessTest" }
|
||||
|
||||
@@ -301,6 +350,23 @@ class FileSystemAccessTest extends InlineExpectationsTest {
|
||||
}
|
||||
}
|
||||
|
||||
class FileSystemWriteAccessTest extends InlineExpectationsTest {
|
||||
FileSystemWriteAccessTest() { this = "FileSystemWriteAccessTest" }
|
||||
|
||||
override string getARelevantTag() { result = "fileWriteData" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(location.getFile().getRelativePath()) and
|
||||
exists(FileSystemWriteAccess write, DataFlow::Node data |
|
||||
data = write.getADataNode() and
|
||||
location = data.getLocation() and
|
||||
element = data.toString() and
|
||||
value = prettyNodeForInlineTest(data) and
|
||||
tag = "fileWriteData"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class PathNormalizationTest extends InlineExpectationsTest {
|
||||
PathNormalizationTest() { this = "PathNormalizationTest" }
|
||||
|
||||
|
||||
@@ -65,6 +65,20 @@ async def redirect_302(request): # $ requestHandler
|
||||
else:
|
||||
raise web.HTTPFound(location="/logout") # $ HttpResponse HttpRedirectResponse mimetype=application/octet-stream redirectLocation="/logout"
|
||||
|
||||
################################################################################
|
||||
# Cookies
|
||||
################################################################################
|
||||
|
||||
@routes.get("/setting_cookie") # $ routeSetup="/setting_cookie"
|
||||
async def setting_cookie(request): # $ requestHandler
|
||||
resp = web.Response(text="foo") # $ HttpResponse mimetype=text/plain responseBody="foo"
|
||||
resp.cookies["key"] = "value" # $ CookieWrite CookieName="key" CookieValue="value"
|
||||
resp.headers["Set-Cookie"] = "key2=value2" # $ MISSING: CookieWrite CookieRawHeader="key2=value2"
|
||||
resp.set_cookie("key3", "value3") # $ CookieWrite CookieName="key3" CookieValue="value3"
|
||||
resp.set_cookie(name="key3", value="value3") # $ CookieWrite CookieName="key3" CookieValue="value3"
|
||||
resp.del_cookie("key4") # $ CookieWrite CookieName="key4"
|
||||
return resp
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = web.Application()
|
||||
|
||||
@@ -103,3 +103,17 @@ class CustomJsonResponse(JsonResponse):
|
||||
|
||||
def safe__custom_json_response(request):
|
||||
return CustomJsonResponse("ACME Responses", {"foo": request.GET.get("foo")}) # $HttpResponse mimetype=application/json MISSING: responseBody=Dict SPURIOUS: responseBody="ACME Responses"
|
||||
|
||||
################################################################################
|
||||
# Cookies
|
||||
################################################################################
|
||||
|
||||
def setting_cookie(request):
|
||||
resp = HttpResponse() # $ HttpResponse mimetype=text/html
|
||||
resp.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value"
|
||||
resp.set_cookie(key="key", value="value") # $ CookieWrite CookieName="key" CookieValue="value"
|
||||
resp.headers["Set-Cookie"] = "key2=value2" # $ MISSING: CookieWrite CookieRawHeader="key2=value2"
|
||||
resp.cookies["key3"] = "value3" # $ CookieWrite CookieName="key3" CookieValue="value3"
|
||||
resp.delete_cookie("key4") # $ CookieWrite CookieName="key4"
|
||||
resp.delete_cookie(key="key4") # $ CookieWrite CookieName="key4"
|
||||
return resp
|
||||
|
||||
@@ -184,6 +184,20 @@ def redirect_simple(): # $requestHandler
|
||||
return resp # $ SPURIOUS: HttpResponse mimetype=text/html responseBody=resp
|
||||
|
||||
|
||||
################################################################################
|
||||
# Cookies
|
||||
################################################################################
|
||||
|
||||
@app.route("/setting_cookie") # $routeSetup="/setting_cookie"
|
||||
def setting_cookie(): # $requestHandler
|
||||
resp = make_response() # $ HttpResponse mimetype=text/html
|
||||
resp.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value"
|
||||
resp.set_cookie(key="key", value="value") # $ CookieWrite CookieName="key" CookieValue="value"
|
||||
resp.headers.add("Set-Cookie", "key2=value2") # $ MISSING: CookieWrite CookieRawHeader="key2=value2"
|
||||
resp.delete_cookie("key3") # $ CookieWrite CookieName="key3"
|
||||
resp.delete_cookie(key="key3") # $ CookieWrite CookieName="key3"
|
||||
return resp # $ SPURIOUS: HttpResponse mimetype=text/html responseBody=resp
|
||||
|
||||
################################################################################
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
from pathlib import Path, PosixPath, WindowsPath
|
||||
|
||||
p = Path("filepath")
|
||||
posix = PosixPath("posix/filepath")
|
||||
windows = WindowsPath("windows/filepath")
|
||||
|
||||
p.chmod(0o777) # $ getAPathArgument=p
|
||||
posix.chmod(0o777) # $ getAPathArgument=posix
|
||||
windows.chmod(0o777) # $ getAPathArgument=windows
|
||||
|
||||
with p.open() as f: # $ getAPathArgument=p
|
||||
f.read()
|
||||
|
||||
p.write_bytes(b"hello") # $ getAPathArgument=p fileWriteData=b"hello"
|
||||
p.write_text("hello") # $ getAPathArgument=p fileWriteData="hello"
|
||||
p.open("wt").write("hello") # $ getAPathArgument=p fileWriteData="hello"
|
||||
|
||||
name = windows.parent.name
|
||||
o = open
|
||||
o(name) # $ getAPathArgument=name
|
||||
|
||||
wb = p.write_bytes
|
||||
wb(b"hello") # $ getAPathArgument=p fileWriteData=b"hello"
|
||||
@@ -1,39 +1,29 @@
|
||||
import builtins
|
||||
import io
|
||||
|
||||
open("filepath") # $getAPathArgument="filepath"
|
||||
open(file="filepath") # $getAPathArgument="filepath"
|
||||
open("filepath") # $ getAPathArgument="filepath"
|
||||
open(file="filepath") # $ getAPathArgument="filepath"
|
||||
|
||||
o = open
|
||||
|
||||
o("filepath") # $getAPathArgument="filepath"
|
||||
o(file="filepath") # $getAPathArgument="filepath"
|
||||
o("filepath") # $ getAPathArgument="filepath"
|
||||
o(file="filepath") # $ getAPathArgument="filepath"
|
||||
|
||||
|
||||
builtins.open("filepath") # $getAPathArgument="filepath"
|
||||
builtins.open(file="filepath") # $getAPathArgument="filepath"
|
||||
builtins.open("filepath") # $ getAPathArgument="filepath"
|
||||
builtins.open(file="filepath") # $ getAPathArgument="filepath"
|
||||
|
||||
|
||||
io.open("filepath") # $getAPathArgument="filepath"
|
||||
io.open(file="filepath") # $getAPathArgument="filepath"
|
||||
io.open("filepath") # $ getAPathArgument="filepath"
|
||||
io.open(file="filepath") # $ getAPathArgument="filepath"
|
||||
|
||||
from pathlib import Path, PosixPath, WindowsPath
|
||||
f = open("path") # $ getAPathArgument="path"
|
||||
f.write("foo") # $ getAPathArgument="path" fileWriteData="foo"
|
||||
lines = ["foo"]
|
||||
f.writelines(lines) # $ getAPathArgument="path" fileWriteData=lines
|
||||
|
||||
p = Path("filepath")
|
||||
posix = PosixPath("posix/filepath")
|
||||
windows = WindowsPath("windows/filepath")
|
||||
|
||||
p.chmod(0o777) # $getAPathArgument=p
|
||||
posix.chmod(0o777) # $getAPathArgument=posix
|
||||
windows.chmod(0o777) # $getAPathArgument=windows
|
||||
def through_function(open_file):
|
||||
open_file.write("foo") # $ fileWriteData="foo" getAPathArgument="path"
|
||||
|
||||
with p.open() as f: # $getAPathArgument=p
|
||||
f.read()
|
||||
|
||||
p.write_bytes(b"hello") # $getAPathArgument=p
|
||||
|
||||
name = windows.parent.name
|
||||
o(name) # $getAPathArgument=name
|
||||
|
||||
wb = p.write_bytes
|
||||
wb(b"hello") # $getAPathArgument=p
|
||||
through_function(f)
|
||||
|
||||
45
python/ql/test/library-tests/frameworks/stdlib/Logging.py
Normal file
45
python/ql/test/library-tests/frameworks/stdlib/Logging.py
Normal file
@@ -0,0 +1,45 @@
|
||||
import logging
|
||||
|
||||
# this bit just included to make this file runable
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
password = "<pass>"
|
||||
msg = "foo %s"
|
||||
|
||||
LOGGER = logging.getLogger("LOGGER")
|
||||
|
||||
logging.info(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
logging.info(msg="hello") # $ loggingInput="hello"
|
||||
|
||||
logging.log(logging.INFO, msg, password) # $ loggingInput=msg loggingInput=password
|
||||
LOGGER.log(logging.INFO, msg, password) # $ loggingInput=msg loggingInput=password
|
||||
|
||||
logging.root.info(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
|
||||
# test of all levels
|
||||
|
||||
logging.critical(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
logging.fatal(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
logging.error(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
logging.warning(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
logging.warn(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
logging.info(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
logging.debug(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
logging.exception(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
|
||||
LOGGER.critical(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
LOGGER.fatal(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
LOGGER.error(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
LOGGER.warning(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
LOGGER.warn(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
LOGGER.info(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
LOGGER.debug(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
LOGGER.exception(msg, password) # $ loggingInput=msg loggingInput=password
|
||||
|
||||
# not sure how to make these print anything, but just to show that it works
|
||||
logging.Logger("foo").info("hello") # $ loggingInput="hello"
|
||||
|
||||
class MyLogger(logging.Logger):
|
||||
pass
|
||||
|
||||
MyLogger("bar").info("hello") # $ loggingInput="hello"
|
||||
@@ -58,6 +58,18 @@ class ExampleConnectionWrite(tornado.web.RequestHandler):
|
||||
stream.write(b"foo stream") # $ MISSING: HttpResponse responseBody=b"foo stream"
|
||||
stream.close()
|
||||
|
||||
################################################################################
|
||||
# Cookies
|
||||
################################################################################
|
||||
|
||||
class CookieWriting(tornado.web.RequestHandler):
|
||||
def get(self): # $ requestHandler
|
||||
self.write("foo") # $ HttpResponse mimetype=text/html responseBody="foo"
|
||||
self.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value"
|
||||
self.set_cookie(name="key", value="value") # $ CookieWrite CookieName="key" CookieValue="value"
|
||||
self.set_header("Set-Cookie", "key2=value2") # $ MISSING: CookieWrite CookieRawHeader="key2=value2"
|
||||
|
||||
|
||||
def make_app():
|
||||
return tornado.web.Application(
|
||||
[
|
||||
@@ -66,6 +78,7 @@ def make_app():
|
||||
(r"/ExampleRedirect", ExampleRedirect), # $ routeSetup="/ExampleRedirect"
|
||||
(r"/ExampleConnectionWrite", ExampleConnectionWrite), # $ routeSetup="/ExampleConnectionWrite"
|
||||
(r"/ExampleConnectionWrite/(stream)", ExampleConnectionWrite), # $ routeSetup="/ExampleConnectionWrite/(stream)"
|
||||
(r"/CookieWriting", CookieWriting), # $ routeSetup="/CookieWriting"
|
||||
],
|
||||
debug=True,
|
||||
)
|
||||
@@ -74,6 +87,7 @@ def make_app():
|
||||
if __name__ == "__main__":
|
||||
import tornado.ioloop
|
||||
|
||||
print("running on http://localhost:8888/")
|
||||
app = make_app()
|
||||
app.listen(8888)
|
||||
tornado.ioloop.IOLoop.current().start()
|
||||
|
||||
@@ -43,16 +43,21 @@ class Redirect(Resource):
|
||||
# requested with curl.
|
||||
return b"hello" # $ SPURIOUS: HttpResponse mimetype=text/html responseBody=b"hello"
|
||||
|
||||
################################################################################
|
||||
# Cookies
|
||||
################################################################################
|
||||
|
||||
class NonHttpBodyOutput(Resource):
|
||||
class CookieWriting(Resource):
|
||||
"""Examples of providing values in response that is not in the body
|
||||
"""
|
||||
def render_GET(self, request: Request): # $ requestHandler
|
||||
request.responseHeaders.addRawHeader("key", "value")
|
||||
request.setHeader("key2", "value")
|
||||
request.addCookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value"
|
||||
request.addCookie(k="key", v="value") # $ CookieWrite CookieName="key" CookieValue="value"
|
||||
val = "key2=value"
|
||||
request.cookies.append(val) # $ CookieWrite CookieRawHeader=val
|
||||
|
||||
request.addCookie("key", "value")
|
||||
request.cookies.append(b"key2=value")
|
||||
request.responseHeaders.addRawHeader("key", "value")
|
||||
request.setHeader("Set-Cookie", "key3=value3") # $ MISSING: CookieWrite CookieRawHeader="key3=value3"
|
||||
|
||||
return b"" # $ HttpResponse mimetype=text/html responseBody=b""
|
||||
|
||||
@@ -62,7 +67,7 @@ root.putChild(b"also-now", AlsoNow())
|
||||
root.putChild(b"later", Later())
|
||||
root.putChild(b"plain-text", PlainText())
|
||||
root.putChild(b"redirect", Redirect())
|
||||
root.putChild(b"non-body", NonHttpBodyOutput())
|
||||
root.putChild(b"setting_cookie", CookieWriting())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
edges
|
||||
| test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:20:48:20:55 | ControlFlowNode for password |
|
||||
| test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:22:58:22:65 | ControlFlowNode for password |
|
||||
| test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:23:58:23:65 | ControlFlowNode for password |
|
||||
| test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:27:40:27:47 | ControlFlowNode for password |
|
||||
| test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:30:58:30:65 | ControlFlowNode for password |
|
||||
nodes
|
||||
| test.py:19:16:19:29 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() |
|
||||
| test.py:20:48:20:55 | ControlFlowNode for password | semmle.label | ControlFlowNode for password |
|
||||
| test.py:22:58:22:65 | ControlFlowNode for password | semmle.label | ControlFlowNode for password |
|
||||
| test.py:23:58:23:65 | ControlFlowNode for password | semmle.label | ControlFlowNode for password |
|
||||
| test.py:27:40:27:47 | ControlFlowNode for password | semmle.label | ControlFlowNode for password |
|
||||
| test.py:30:58:30:65 | ControlFlowNode for password | semmle.label | ControlFlowNode for password |
|
||||
| test.py:34:30:34:39 | ControlFlowNode for get_cert() | semmle.label | ControlFlowNode for get_cert() |
|
||||
| test.py:37:11:37:24 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() |
|
||||
| test.py:39:22:39:35 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() |
|
||||
| test.py:40:22:40:35 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() |
|
||||
#select
|
||||
| test.py:20:48:20:55 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:20:48:20:55 | ControlFlowNode for password | $@ is logged here. | test.py:19:16:19:29 | ControlFlowNode for get_password() | Sensitive data (password) |
|
||||
| test.py:22:58:22:65 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:22:58:22:65 | ControlFlowNode for password | $@ is logged here. | test.py:19:16:19:29 | ControlFlowNode for get_password() | Sensitive data (password) |
|
||||
| test.py:23:58:23:65 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:23:58:23:65 | ControlFlowNode for password | $@ is logged here. | test.py:19:16:19:29 | ControlFlowNode for get_password() | Sensitive data (password) |
|
||||
| test.py:27:40:27:47 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:27:40:27:47 | ControlFlowNode for password | $@ is logged here. | test.py:19:16:19:29 | ControlFlowNode for get_password() | Sensitive data (password) |
|
||||
| test.py:30:58:30:65 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:30:58:30:65 | ControlFlowNode for password | $@ is logged here. | test.py:19:16:19:29 | ControlFlowNode for get_password() | Sensitive data (password) |
|
||||
| test.py:34:30:34:39 | ControlFlowNode for get_cert() | test.py:34:30:34:39 | ControlFlowNode for get_cert() | test.py:34:30:34:39 | ControlFlowNode for get_cert() | $@ is logged here. | test.py:34:30:34:39 | ControlFlowNode for get_cert() | Sensitive data (certificate) |
|
||||
| test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | $@ is logged here. | test.py:37:11:37:24 | ControlFlowNode for get_password() | Sensitive data (password) |
|
||||
| test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | $@ is logged here. | test.py:39:22:39:35 | ControlFlowNode for get_password() | Sensitive data (password) |
|
||||
| test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | $@ is logged here. | test.py:40:22:40:35 | ControlFlowNode for get_password() | Sensitive data (password) |
|
||||
@@ -0,0 +1,46 @@
|
||||
import logging
|
||||
import sys
|
||||
|
||||
LOGGER = logging.getLogger("LOGGER")
|
||||
|
||||
def get_logger():
|
||||
return LOGGER
|
||||
|
||||
|
||||
def get_password():
|
||||
return "<PASSWORD>"
|
||||
|
||||
|
||||
def get_cert():
|
||||
return "<CERT>"
|
||||
|
||||
|
||||
def log_password():
|
||||
password = get_password()
|
||||
logging.info("logging.info Password '%s'", password) # NOT OK
|
||||
|
||||
LOGGER.log(logging.INFO, "LOGGER.log Password '%s'", password) # NOT OK
|
||||
logging.root.info("logging.root.info Password '%s'", password) # NOT OK
|
||||
|
||||
# name of logger variable should not matter
|
||||
foo = LOGGER
|
||||
foo.info("foo.info Password '%s'", password) # NOT OK
|
||||
|
||||
# return value from function
|
||||
get_logger().info("get_logger().info Password '%s'", password) # NOT OK
|
||||
|
||||
|
||||
def log_cert():
|
||||
logging.debug("Cert=%s", get_cert()) # NOT OK
|
||||
|
||||
def print_password():
|
||||
print(get_password()) # NOT OK
|
||||
|
||||
sys.stdout.write(get_password()) # NOT OK
|
||||
sys.stderr.write(get_password()) # NOT OK
|
||||
|
||||
if __name__ == "__main__":
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
log_password()
|
||||
log_cert()
|
||||
print_password()
|
||||
@@ -0,0 +1,13 @@
|
||||
edges
|
||||
| test.py:9:12:9:21 | ControlFlowNode for get_cert() | test.py:12:21:12:24 | ControlFlowNode for cert |
|
||||
| test.py:9:12:9:21 | ControlFlowNode for get_cert() | test.py:13:22:13:41 | ControlFlowNode for Attribute() |
|
||||
| test.py:9:12:9:21 | ControlFlowNode for get_cert() | test.py:15:26:15:29 | ControlFlowNode for cert |
|
||||
nodes
|
||||
| test.py:9:12:9:21 | ControlFlowNode for get_cert() | semmle.label | ControlFlowNode for get_cert() |
|
||||
| test.py:12:21:12:24 | ControlFlowNode for cert | semmle.label | ControlFlowNode for cert |
|
||||
| test.py:13:22:13:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:15:26:15:29 | ControlFlowNode for cert | semmle.label | ControlFlowNode for cert |
|
||||
#select
|
||||
| test.py:12:21:12:24 | ControlFlowNode for cert | test.py:9:12:9:21 | ControlFlowNode for get_cert() | test.py:12:21:12:24 | ControlFlowNode for cert | $@ is stored here. | test.py:9:12:9:21 | ControlFlowNode for get_cert() | Sensitive data (certificate) |
|
||||
| test.py:13:22:13:41 | ControlFlowNode for Attribute() | test.py:9:12:9:21 | ControlFlowNode for get_cert() | test.py:13:22:13:41 | ControlFlowNode for Attribute() | $@ is stored here. | test.py:9:12:9:21 | ControlFlowNode for get_cert() | Sensitive data (certificate) |
|
||||
| test.py:15:26:15:29 | ControlFlowNode for cert | test.py:9:12:9:21 | ControlFlowNode for get_cert() | test.py:15:26:15:29 | ControlFlowNode for cert | $@ is stored here. | test.py:9:12:9:21 | ControlFlowNode for get_cert() | Sensitive data (certificate) |
|
||||
@@ -0,0 +1,15 @@
|
||||
import pathlib
|
||||
|
||||
|
||||
def get_cert():
|
||||
return "<CERT>"
|
||||
|
||||
|
||||
def write_password(filename):
|
||||
cert = get_cert()
|
||||
|
||||
path = pathlib.Path(filename)
|
||||
path.write_text(cert) # NOT OK
|
||||
path.write_bytes(cert.encode("utf-8")) # NOT OK
|
||||
|
||||
path.open("w").write(cert) # NOT OK
|
||||
@@ -0,0 +1,20 @@
|
||||
edges
|
||||
| password_in_cookie.py:7:16:7:43 | ControlFlowNode for Attribute() | password_in_cookie.py:9:33:9:40 | ControlFlowNode for password |
|
||||
| password_in_cookie.py:14:16:14:43 | ControlFlowNode for Attribute() | password_in_cookie.py:16:33:16:40 | ControlFlowNode for password |
|
||||
| test.py:6:12:6:21 | ControlFlowNode for get_cert() | test.py:8:20:8:23 | ControlFlowNode for cert |
|
||||
| test.py:6:12:6:21 | ControlFlowNode for get_cert() | test.py:9:17:9:29 | ControlFlowNode for List |
|
||||
| test.py:9:17:9:29 | ControlFlowNode for List | test.py:10:25:10:29 | ControlFlowNode for lines |
|
||||
nodes
|
||||
| password_in_cookie.py:7:16:7:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| password_in_cookie.py:9:33:9:40 | ControlFlowNode for password | semmle.label | ControlFlowNode for password |
|
||||
| password_in_cookie.py:14:16:14:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| password_in_cookie.py:16:33:16:40 | ControlFlowNode for password | semmle.label | ControlFlowNode for password |
|
||||
| test.py:6:12:6:21 | ControlFlowNode for get_cert() | semmle.label | ControlFlowNode for get_cert() |
|
||||
| test.py:8:20:8:23 | ControlFlowNode for cert | semmle.label | ControlFlowNode for cert |
|
||||
| test.py:9:17:9:29 | ControlFlowNode for List | semmle.label | ControlFlowNode for List |
|
||||
| test.py:10:25:10:29 | ControlFlowNode for lines | semmle.label | ControlFlowNode for lines |
|
||||
#select
|
||||
| password_in_cookie.py:9:33:9:40 | ControlFlowNode for password | password_in_cookie.py:7:16:7:43 | ControlFlowNode for Attribute() | password_in_cookie.py:9:33:9:40 | ControlFlowNode for password | $@ is stored here. | password_in_cookie.py:7:16:7:43 | ControlFlowNode for Attribute() | Sensitive data (password) |
|
||||
| password_in_cookie.py:16:33:16:40 | ControlFlowNode for password | password_in_cookie.py:14:16:14:43 | ControlFlowNode for Attribute() | password_in_cookie.py:16:33:16:40 | ControlFlowNode for password | $@ is stored here. | password_in_cookie.py:14:16:14:43 | ControlFlowNode for Attribute() | Sensitive data (password) |
|
||||
| test.py:8:20:8:23 | ControlFlowNode for cert | test.py:6:12:6:21 | ControlFlowNode for get_cert() | test.py:8:20:8:23 | ControlFlowNode for cert | $@ is stored here. | test.py:6:12:6:21 | ControlFlowNode for get_cert() | Sensitive data (certificate) |
|
||||
| test.py:10:25:10:29 | ControlFlowNode for lines | test.py:6:12:6:21 | ControlFlowNode for get_cert() | test.py:10:25:10:29 | ControlFlowNode for lines | $@ is stored here. | test.py:6:12:6:21 | ControlFlowNode for get_cert() | Sensitive data (certificate) |
|
||||
@@ -0,0 +1 @@
|
||||
Security/CWE-312/CleartextStorage.ql
|
||||
@@ -6,12 +6,12 @@ app = Flask("Leak password")
|
||||
def index():
|
||||
password = request.args.get("password")
|
||||
resp = make_response(render_template(...))
|
||||
resp.set_cookie("password", password)
|
||||
resp.set_cookie("password", password) # NOT OK
|
||||
return resp
|
||||
|
||||
@app.route('/')
|
||||
def index2():
|
||||
password = request.args.get("password")
|
||||
resp = Response(...)
|
||||
resp.set_cookie("password", password)
|
||||
resp.set_cookie("password", password) # NOT OK
|
||||
return resp
|
||||
@@ -0,0 +1,10 @@
|
||||
def get_cert():
|
||||
return "<CERT>"
|
||||
|
||||
|
||||
def write_cert(filename):
|
||||
cert = get_cert()
|
||||
with open(filename, "w") as file:
|
||||
file.write(cert) # NOT OK
|
||||
lines = [cert + "\n"]
|
||||
file.writelines(lines) # NOT OK
|
||||
@@ -1,10 +0,0 @@
|
||||
edges
|
||||
| password_in_cookie.py:7:16:7:43 | a password | password_in_cookie.py:9:33:9:40 | a password |
|
||||
| password_in_cookie.py:14:16:14:43 | a password | password_in_cookie.py:16:33:16:40 | a password |
|
||||
| test.py:7:16:7:29 | a password | test.py:8:35:8:42 | a password |
|
||||
| test.py:7:16:7:29 | a password | test.py:8:35:8:42 | a password |
|
||||
| test.py:20:12:20:21 | a certificate or key | test.py:22:20:22:23 | a certificate or key |
|
||||
#select
|
||||
| test.py:8:35:8:42 | password | test.py:7:16:7:29 | a password | test.py:8:35:8:42 | a password | Sensitive data returned by $@ is logged here. | test.py:7:16:7:29 | get_password() | a call returning a password |
|
||||
| test.py:14:30:14:39 | get_cert() | test.py:14:30:14:39 | a certificate or key | test.py:14:30:14:39 | a certificate or key | Sensitive data returned by $@ is logged here. | test.py:14:30:14:39 | get_cert() | a call returning a certificate or key |
|
||||
| test.py:17:11:17:24 | get_password() | test.py:17:11:17:24 | a password | test.py:17:11:17:24 | a password | Sensitive data returned by $@ is logged here. | test.py:17:11:17:24 | get_password() | a call returning a password |
|
||||
@@ -1,12 +0,0 @@
|
||||
edges
|
||||
| password_in_cookie.py:7:16:7:43 | a password | password_in_cookie.py:9:33:9:40 | a password |
|
||||
| password_in_cookie.py:7:16:7:43 | a password | password_in_cookie.py:9:33:9:40 | a password |
|
||||
| password_in_cookie.py:14:16:14:43 | a password | password_in_cookie.py:16:33:16:40 | a password |
|
||||
| password_in_cookie.py:14:16:14:43 | a password | password_in_cookie.py:16:33:16:40 | a password |
|
||||
| test.py:7:16:7:29 | a password | test.py:8:35:8:42 | a password |
|
||||
| test.py:20:12:20:21 | a certificate or key | test.py:22:20:22:23 | a certificate or key |
|
||||
| test.py:20:12:20:21 | a certificate or key | test.py:22:20:22:23 | a certificate or key |
|
||||
#select
|
||||
| password_in_cookie.py:9:33:9:40 | password | password_in_cookie.py:7:16:7:43 | a password | password_in_cookie.py:9:33:9:40 | a password | Sensitive data from $@ is stored here. | password_in_cookie.py:7:16:7:43 | Attribute() | a request parameter containing a password |
|
||||
| password_in_cookie.py:16:33:16:40 | password | password_in_cookie.py:14:16:14:43 | a password | password_in_cookie.py:16:33:16:40 | a password | Sensitive data from $@ is stored here. | password_in_cookie.py:14:16:14:43 | Attribute() | a request parameter containing a password |
|
||||
| test.py:22:20:22:23 | cert | test.py:20:12:20:21 | a certificate or key | test.py:22:20:22:23 | a certificate or key | Sensitive data from $@ is stored here. | test.py:20:12:20:21 | get_cert() | a call returning a certificate or key |
|
||||
@@ -1 +0,0 @@
|
||||
semmle-extractor-options: -p ../lib/ --max-import-depth=3
|
||||
@@ -1,22 +0,0 @@
|
||||
#Don't import logging; it transitively imports a lot of stuff
|
||||
|
||||
def get_password():
|
||||
pass
|
||||
|
||||
def log_password():
|
||||
password = get_password()
|
||||
logging.info("Password '%s'", password)
|
||||
|
||||
def get_cert():
|
||||
pass
|
||||
|
||||
def log_cert():
|
||||
logging.debug("Cert=%s", get_cert())
|
||||
|
||||
def print_password():
|
||||
print(get_password())
|
||||
|
||||
def write_cert(filename):
|
||||
cert = get_cert()
|
||||
with open(filename, "w") as file:
|
||||
file.write(cert)
|
||||
Reference in New Issue
Block a user