Python: Add tests for twisted

These were largely based on the old tests in
6011cb74f8/python/ql/test/library-tests/web/twisted/test.py
This commit is contained in:
Rasmus Wriedt Larsen
2021-06-08 15:06:10 +02:00
parent 44b9de04e5
commit 151a733ff2
7 changed files with 208 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
import python
import experimental.meta.ConceptsTest
class DedicatedResponseTest extends HttpServerHttpResponseTest {
DedicatedResponseTest() { file.getShortName() = "response_test.py" }
}
class OtherResponseTest extends HttpServerHttpResponseTest {
OtherResponseTest() { not this instanceof DedicatedResponseTest }
override string getARelevantTag() { result = "HttpResponse" }
}

View File

@@ -0,0 +1,3 @@
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures

View File

@@ -0,0 +1 @@
import experimental.meta.InlineTaintTest

View File

@@ -0,0 +1,75 @@
from twisted.web.server import Site, Request, NOT_DONE_YET
from twisted.web.resource import Resource
from twisted.internet import reactor, endpoints, defer
root = Resource()
class Now(Resource):
def render(self, request: Request):
return b"now"
class AlsoNow(Resource):
def render(self, request: Request):
request.write(b"also now")
return b""
def process_later(request: Request):
print("process_later called")
request.write(b"later")
request.finish()
class Later(Resource):
def render(self, request: Request):
# process the request in 1 second
print("setting up callback for process_later")
reactor.callLater(1, process_later, request)
return NOT_DONE_YET
class PlainText(Resource):
def render(self, request: Request):
request.setHeader(b"content-type", "text/plain")
return b"this is plain text"
class Redirect(Resource):
def render_GET(self, request: Request):
request.redirect("/new-location")
# By default, this `hello` output is not returned... not even when
# requested with curl.
return b"hello"
class NonHttpBodyOutput(Resource):
"""Examples of provides values in response that is not in the body
"""
def render_GET(self, request: Request):
request.responseHeaders.addRawHeader("key", "value")
request.setHeader("key2", "value")
request.addCookie("key", "value")
request.cookies.append(b"key2=value")
return b""
root.putChild(b"now", Now())
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())
if __name__ == "__main__":
factory = Site(root)
endpoint = endpoints.TCP4ServerEndpoint(reactor, 8880)
endpoint.listen(factory)
print("Will run on http://localhost:8880")
reactor.run()

View File

@@ -0,0 +1,47 @@
from twisted.web.server import Site, Request
from twisted.web.resource import Resource
from twisted.internet import reactor, endpoints
root = Resource()
class Foo(Resource):
def render(self, request: Request):
print(f"{request.content=}")
print(f"{request.cookies=}")
print(f"{request.received_cookies=}")
return b"I am Foo"
root.putChild(b"foo", Foo())
class Child(Resource):
def __init__(self, name):
self.name = name.decode("utf-8")
def render_GET(self, request):
return f"Hi, I'm child '{self.name}'".encode("utf-8")
class Parent(Resource):
def getChild(self, path, request):
print(path, type(path))
return Child(path)
def render_GET(self, request):
return b"Hi, I'm parent"
root.putChild(b"parent", Parent())
if __name__ == "__main__":
factory = Site(root)
endpoint = endpoints.TCP4ServerEndpoint(reactor, 8880)
endpoint.listen(factory)
print("Will run on http://localhost:8880")
reactor.run()

View File

@@ -0,0 +1,70 @@
from twisted.web.resource import Resource
from twisted.web.server import Request
class MyTaintTest(Resource):
def getChild(self, path, request):
ensure_tainted(path, request) # $ MISSING: tainted
def render(self, request):
ensure_tainted(request) # $ MISSING: tainted
def render_GET(self, request: Request):
# see https://twistedmatrix.com/documents/21.2.0/api/twisted.web.server.Request.html
ensure_tainted(
request, # $ MISSING: tainted
request.uri, # $ MISSING: tainted
request.path, # $ MISSING: tainted
request.prepath, # $ MISSING: tainted
request.postpath, # $ MISSING: tainted
# file-like
request.content, # $ MISSING: tainted
request.content.read(), # $ MISSING: tainted
# Dict[bytes, List[bytes]] (for query args)
request.args, # $ MISSING: tainted
request.args[b"key"], # $ MISSING: tainted
request.args[b"key"][0], # $ MISSING: tainted
request.args.get(b"key"), # $ MISSING: tainted
request.args.get(b"key")[0], # $ MISSING: tainted
request.received_cookies, # $ MISSING: tainted
request.received_cookies["key"], # $ MISSING: tainted
request.received_cookies.get("key"), # $ MISSING: tainted
request.getCookie(b"key"), # $ MISSING: tainted
# twisted.web.http_headers.Headers
# see https://twistedmatrix.com/documents/21.2.0/api/twisted.web.http_headers.Headers.html
request.requestHeaders, # $ MISSING: tainted
request.requestHeaders.getRawHeaders("key"), # $ MISSING: tainted
request.requestHeaders.getRawHeaders("key")[0], # $ MISSING: tainted
request.requestHeaders.getAllRawHeaders(), # $ MISSING: tainted
list(request.requestHeaders.getAllRawHeaders()), # $ MISSING: tainted
request.getHeader("key"), # $ MISSING: tainted
request.getAllHeaders(), # $ MISSING: tainted
request.getAllHeaders()["key"], # $ MISSING: tainted
request.user, # $ MISSING: tainted
request.getUser(), # $ MISSING: tainted
request.password, # $ MISSING: tainted
request.getPassword(), # $ MISSING: tainted
request.host, # $ MISSING: tainted
request.getHost(), # $ MISSING: tainted
request.getRequestHostname(), # $ MISSING: tainted
)
# technically user-controlled, but unlike to lead to vulnerabilities.
ensure_not_tainted(
request.method,
)
# not tainted at all
ensure_not_tainted(
# outgoing things
request.cookies,
request.responseHeaders,
)