Skip to content

Commit ee1ba71

Browse files
author
Alvaro Muñoz
committed
add tests
1 parent 10cd649 commit ee1ba71

File tree

3 files changed

+142
-0
lines changed

3 files changed

+142
-0
lines changed

python/ql/test/library-tests/frameworks/aiohttp/client_request.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,5 @@ async def test():
3333
assert context.verify_mode == ssl.VerifyMode.CERT_NONE
3434

3535
s.get("url", ssl=context) # $ clientRequestUrlPart="url" MISSING: clientRequestCertValidationDisabled
36+
37+
s.ws_connect("url") # $ clientRequestUrlPart="url"

python/ql/test/library-tests/frameworks/aiohttp/response_test.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ async def html_text(request): # $ requestHandler
2323
async def html_body(request): # $ requestHandler
2424
return web.Response(body=b"foo", content_type="text/html") # $ HttpResponse mimetype=text/html responseBody=b"foo"
2525

26+
@routes.get("/html_body_header") # $ routeSetup="/html_body_header"
27+
async def html_body_header(request): # $ requestHandler
28+
return web.Response(
29+
headers={"content-type": "text/html"},
30+
text="<script>window.close()</script>Success! This window can be closed",
31+
)
2632

2733
@routes.get("/html_body_set_later") # $ routeSetup="/html_body_set_later"
2834
async def html_body_set_later(request): # $ requestHandler
@@ -65,6 +71,11 @@ async def redirect_302(request): # $ requestHandler
6571
else:
6672
raise web.HTTPFound(location="/logout") # $ HttpResponse HttpRedirectResponse mimetype=application/octet-stream redirectLocation="/logout"
6773

74+
@routes.get("/serve_file") # $ routeSetup="/serve_file"
75+
async def serve_file(request): # $ requestHandler
76+
filename = request.query.getone("filename"),
77+
return web.FileResponse(filename) # $ HttpResponse mimetype=application/octet-stream
78+
6879
################################################################################
6980
# Cookies
7081
################################################################################

python/ql/test/library-tests/frameworks/aiohttp/taint_test.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,134 @@
11
from aiohttp import web
22

3+
async def test_heuristic_taint(request: web.Request):
4+
ensure_tainted(
5+
# see https://docs.aiohttp.org/en/stable/web_reference.html#request-and-base-request
6+
request, # $ tainted
7+
8+
# yarl.URL (see `yarl` framework tests)
9+
request.url, # $ tainted
10+
request.url.human_repr(), # $ tainted
11+
request.rel_url, # $ tainted
12+
request.rel_url.human_repr(), # $ tainted
13+
14+
request.forwarded, # $ tainted
15+
16+
request.host, # $ tainted
17+
request.remote, # $ tainted
18+
request.path, # $ tainted
19+
request.path_qs, # $ tainted
20+
request.raw_path, # $ tainted
21+
22+
# dict-like for captured parts of the URL
23+
request.match_info, # $ tainted
24+
request.match_info["key"], # $ tainted
25+
request.match_info.get("key"), # $ tainted
26+
27+
# multidict.MultiDictProxy[str] (see `multidict` framework tests)
28+
request.query, # $ tainted
29+
request.query.getone("key"), # $ tainted
30+
31+
# multidict.CIMultiDictProxy[str] (see `multidict` framework tests)
32+
request.headers, # $ tainted
33+
request.headers.getone("key"), # $ tainted
34+
35+
36+
37+
# dict-like (readonly)
38+
request.cookies, # $ tainted
39+
request.cookies["key"], # $ tainted
40+
request.cookies.get("key"), # $ tainted
41+
request.cookies.keys(), # $ tainted
42+
request.cookies.values(), # $ tainted
43+
request.cookies.items(), # $ tainted
44+
list(request.cookies), # $ tainted
45+
iter(request.cookies), # $ tainted
46+
47+
48+
# aiohttp.StreamReader
49+
# see https://docs.aiohttp.org/en/stable/streams.html#aiohttp.StreamReader
50+
request.content, # $ tainted
51+
await request.content.read(), # $ tainted
52+
await request.content.readany(), # $ tainted
53+
await request.content.readexactly(42), # $ tainted
54+
await request.content.readline(), # $ tainted
55+
await request.content.readchunk(), # $ tainted
56+
(await request.content.readchunk())[0], # $ tainted
57+
[line async for line in request.content], # $ tainted
58+
[data async for data in request.content.iter_chunked(1024)], # $ tainted
59+
[data async for data in request.content.iter_any()], # $ tainted
60+
[data async for data, _ in request.content.iter_chunks()], # $ tainted
61+
request.content.read_nowait(), # $ tainted
62+
63+
# aiohttp.StreamReader
64+
request._payload, # $ tainted
65+
await request._payload.readany(), # $ tainted
66+
67+
request.content_type, # $ tainted
68+
request.charset, # $ tainted
69+
70+
request.http_range, # $ tainted
71+
72+
# Optional[datetime]
73+
request.if_modified_since, # $ tainted
74+
request.if_unmodified_since, # $ tainted
75+
request.if_range, # $ tainted
76+
77+
request.clone(scheme="https"), # $ tainted
78+
79+
# asyncio.Transport
80+
# https://docs.python.org/3/library/asyncio-protocol.html#asyncio-transport
81+
# example given in https://docs.aiohttp.org/en/stable/web_reference.html#aiohttp.web.BaseRequest.transport
82+
# uses `peername` to get IP address of client
83+
request.transport, # $ tainted
84+
request.transport.get_extra_info("key"), # $ MISSING: tainted
85+
86+
# Like request.transport.get_extra_info
87+
request.get_extra_info("key"), # $ tainted
88+
89+
# Like request.transport.get_extra_info
90+
request.protocol.transport.get_extra_info("key"), # $ MISSING: tainted
91+
92+
# bytes
93+
await request.read(), # $ tainted
94+
95+
# str
96+
await request.text(), # $ tainted
97+
98+
# obj
99+
await request.json(), # $ tainted
100+
101+
# aiohttp.multipart.MultipartReader
102+
await request.multipart(), # $ tainted
103+
104+
# multidict.MultiDictProxy[str] (see `multidict` framework tests)
105+
await request.post(), # $ tainted
106+
(await request.post()).getone("key"), # $ tainted
107+
)
108+
109+
# things that are technically controlled by sender of request,
110+
# but doesn't seem that likely for exploitation.
111+
ensure_not_tainted(
112+
request.method,
113+
request.version,
114+
request.scheme,
115+
request.secure,
116+
request.keep_alive,
117+
118+
request.content_length,
119+
request.body_exists,
120+
request.has_body,
121+
request.can_read_body,
122+
)
123+
124+
ensure_not_tainted(
125+
request.loop,
126+
127+
request.app,
128+
request.config_dict,
129+
)
130+
131+
3132
async def test_taint(request: web.Request): # $ requestHandler
4133

5134
ensure_tainted(

0 commit comments

Comments
 (0)