Skip to content

Commit c69b857

Browse files
committed
1 parent c4b618d commit c69b857

File tree

4 files changed

+55
-31
lines changed

4 files changed

+55
-31
lines changed

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

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ private import semmle.python.dataflow.new.TaintTracking
1010
private import semmle.python.Concepts
1111
private import semmle.python.ApiGraphs
1212
private import semmle.python.frameworks.internal.PoorMansFunctionResolution
13+
private import semmle.python.frameworks.internal.SelfRefMixin
1314
private import semmle.python.frameworks.Multidict
1415
private import semmle.python.frameworks.Yarl
1516

@@ -251,7 +252,7 @@ module AiohttpWebModel {
251252
}
252253

253254
/** A class that we consider a aiohttp.web View class. */
254-
abstract class AiohttpViewClass extends Class {
255+
abstract class AiohttpViewClass extends Class, SelfRefMixin {
255256
/** Gets a function that could handle incoming requests, if any. */
256257
Function getARequestHandler() {
257258
// TODO: This doesn't handle attribute assignment. Should be OK, but analysis is not as complete as with
@@ -341,16 +342,23 @@ module AiohttpWebModel {
341342
this.getParameter() =
342343
max(Parameter param, int i | param = requestHandler.getArg(i) | param order by i)
343344
)
344-
or
345-
exists(AiohttpViewClass vc |
346-
// TODO
347-
none()
348-
)
349345
}
350346

351347
override string getSourceType() { result = "aiohttp.web.Request" }
352348
}
353349

350+
class AiohttpViewClassRequestAttributeRead extends Request::InstanceSource,
351+
RemoteFlowSource::Range, DataFlow::Node {
352+
AiohttpViewClassRequestAttributeRead() {
353+
this.(DataFlow::AttrRead).getObject() = any(AiohttpViewClass vc).getASelfRef() and
354+
this.(DataFlow::AttrRead).getAttributeName() = "request"
355+
}
356+
357+
override string getSourceType() {
358+
result = "aiohttp.web.Request from self.request in View class"
359+
}
360+
}
361+
354362
/**
355363
* Taint propagation for `aiohttp.web.Request`.
356364
*

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

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ private import semmle.python.ApiGraphs
1212
private import semmle.python.frameworks.PEP249
1313
private import semmle.python.regex
1414
private import semmle.python.frameworks.internal.PoorMansFunctionResolution
15+
private import semmle.python.frameworks.internal.SelfRefMixin
1516

1617
/**
1718
* Provides models for the `django` PyPI package.
@@ -1388,31 +1389,7 @@ private module PrivateDjango {
13881389
// Helpers
13891390
// ---------------------------------------------------------------------------
13901391

1391-
/** Adds the `getASelfRef` member predicate when modeling a class. */
1392-
abstract private class SelfRefMixin extends Class {
1393-
/**
1394-
* Gets a reference to instances of this class, originating from a self parameter of
1395-
* a method defined on this class.
1396-
*
1397-
* Note: TODO: This doesn't take MRO into account
1398-
* Note: TODO: This doesn't take staticmethod/classmethod into account
1399-
*/
1400-
private DataFlow::LocalSourceNode getASelfRef(DataFlow::TypeTracker t) {
1401-
t.start() and
1402-
result.(DataFlow::ParameterNode).getParameter() = this.getAMethod().getArg(0)
1403-
or
1404-
exists(DataFlow::TypeTracker t2 | result = this.getASelfRef(t2).track(t2, t))
1405-
}
14061392

1407-
/**
1408-
* Gets a reference to instances of this class, originating from a self parameter of
1409-
* a method defined on this class.
1410-
*
1411-
* Note: TODO: This doesn't take MRO into account
1412-
* Note: TODO: This doesn't take staticmethod/classmethod into account
1413-
*/
1414-
DataFlow::Node getASelfRef() { this.getASelfRef(DataFlow::TypeTracker::end()).flowsTo(result) }
1415-
}
14161393

14171394
// ---------------------------------------------------------------------------
14181395
// Form and form field modeling
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* INTERNAL: Do not use.
3+
*
4+
* Provides the `SelfRefMixin` class.
5+
*/
6+
7+
private import python
8+
private import semmle.python.dataflow.new.DataFlow
9+
10+
/**
11+
* INTERNAL: Do not use.
12+
*
13+
* Adds the `getASelfRef` member predicate when modeling a class.
14+
*/
15+
abstract class SelfRefMixin extends Class {
16+
/**
17+
* Gets a reference to instances of this class, originating from a self parameter of
18+
* a method defined on this class.
19+
*
20+
* Note: TODO: This doesn't take MRO into account
21+
* Note: TODO: This doesn't take staticmethod/classmethod into account
22+
*/
23+
private DataFlow::LocalSourceNode getASelfRef(DataFlow::TypeTracker t) {
24+
t.start() and
25+
result.(DataFlow::ParameterNode).getParameter() = this.getAMethod().getArg(0)
26+
or
27+
exists(DataFlow::TypeTracker t2 | result = this.getASelfRef(t2).track(t2, t))
28+
}
29+
30+
/**
31+
* Gets a reference to instances of this class, originating from a self parameter of
32+
* a method defined on this class.
33+
*
34+
* Note: TODO: This doesn't take MRO into account
35+
* Note: TODO: This doesn't take staticmethod/classmethod into account
36+
*/
37+
DataFlow::Node getASelfRef() { this.getASelfRef(DataFlow::TypeTracker::end()).flowsTo(result) }
38+
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,8 @@ async def test_taint(request: web.Request): # $ requestHandler
196196
class TaintTestClass(web.View):
197197
def get(self): # $ requestHandler
198198
ensure_tainted(
199-
self.request, # $ MISSING: tainted
199+
self.request, # $ tainted
200+
self.request.url # $ tainted
200201
)
201202

202203

0 commit comments

Comments
 (0)