Skip to content

Commit dd131e6

Browse files
committed
Python: Add taint-step for methods on aiohttp.web.Request
1 parent 63c7fa0 commit dd131e6

File tree

2 files changed

+23
-12
lines changed

2 files changed

+23
-12
lines changed

python/ql/src/semmle/python/frameworks/Aiohttp.qll

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -211,12 +211,23 @@ module AiohttpWebModel {
211211
private class AiohttpRequestAdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
212212
override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
213213
// Methods
214-
exists(string method_name | method_name in ["TODO"] |
215-
// Method access (obj -> obj.meth)
216-
none()
214+
//
215+
// TODO: When we have tools that make it easy, model these properly to handle
216+
// `meth = obj.meth; meth()`. Until then, we'll use this more syntactic approach
217+
// (since it allows us to at least capture the most common cases).
218+
nodeFrom = Request::instance() and
219+
exists(DataFlow::AttrRead attr | attr.getObject() = nodeFrom |
220+
// normal methods
221+
attr.getAttributeName() in ["clone", "get_extra_info"] and
222+
nodeTo.(DataFlow::CallCfgNode).getFunction() = attr
217223
or
218-
// Method call (obj.meth -> obj.meth())
219-
none()
224+
// async methods
225+
exists(Await await, DataFlow::CallCfgNode call |
226+
attr.getAttributeName() in ["read", "text", "json", "multipart", "post"] and
227+
call.getFunction() = attr and
228+
await.getValue() = call.asExpr() and
229+
nodeTo.asExpr() = await
230+
)
220231
)
221232
or
222233
// Attributes

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,25 +81,25 @@ async def test_taint(request: web.Request): # $ requestHandler
8181
request.if_unmodified_since, # $ tainted
8282
request.if_range, # $ tainted
8383

84-
request.clone(scheme="https"), # $ MISSING: tainted
84+
request.clone(scheme="https"), # $ tainted
8585

8686
# TODO: like request.transport.get_extra_info
87-
request.get_extra_info("key"), # $ MISSING: tainted
87+
request.get_extra_info("key"), # $ tainted
8888

8989
# bytes
90-
await request.read(), # $ MISSING: tainted
90+
await request.read(), # $ tainted
9191

9292
# str
93-
await request.text(), # $ MISSING: tainted
93+
await request.text(), # $ tainted
9494

9595
# obj
96-
await request.json(), # $ MISSING: tainted
96+
await request.json(), # $ tainted
9797

9898
# aiohttp.multipart.MultipartReader
99-
await request.multipart(), # $ MISSING: tainted
99+
await request.multipart(), # $ tainted
100100

101101
# multidict.MultiDictProxy[str]
102-
await request.post(), # $ MISSING: tainted
102+
await request.post(), # $ tainted
103103
(await request.post()).getone("key"), # $ MISSING: tainted
104104
)
105105

0 commit comments

Comments
 (0)