Skip to content

Commit 51b543c

Browse files
committed
Python: Model taint for django request methods
1 parent bced467 commit 51b543c

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed

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

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1892,9 +1892,30 @@ private module PrivateDjango {
18921892
// (since it allows us to at least capture the most common cases).
18931893
nodeFrom = django::http::request::HttpRequest::instance() and
18941894
exists(DataFlow::AttrRead attr | attr.getObject() = nodeFrom |
1895-
attr.getAttributeName() in ["TODO"] and
1895+
attr.getAttributeName() in [
1896+
"get_full_path", "get_full_path_info", "read", "readline", "readlines"
1897+
] and
1898+
nodeTo.(DataFlow::CallCfgNode).getFunction() = attr
1899+
)
1900+
or
1901+
// special handling of the `build_absolute_uri` method, see
1902+
// https://docs.djangoproject.com/en/3.0/ref/request-response/#django.http.HttpRequest.build_absolute_uri
1903+
exists(DataFlow::AttrRead attr, DataFlow::CallCfgNode call, DataFlow::Node instance |
1904+
instance = django::http::request::HttpRequest::instance() and
1905+
attr.getObject() = instance
1906+
|
1907+
attr.getAttributeName() = "build_absolute_uri" and
18961908
nodeTo.(DataFlow::CallCfgNode).getFunction() = attr and
1897-
none()
1909+
call = nodeTo and
1910+
(
1911+
not exists(call.getArg(_)) and
1912+
not exists(call.getArgByName(_)) and
1913+
nodeFrom = instance
1914+
or
1915+
nodeFrom = call.getArg(0)
1916+
or
1917+
nodeFrom = call.getArgByName("location")
1918+
)
18981919
)
18991920
or
19001921
// Attributes
@@ -1920,7 +1941,6 @@ private module PrivateDjango {
19201941
// TODO: Model ResolverMatch
19211942
"resolver_match"
19221943
]
1923-
// TODO: Handle calls to methods
19241944
// TODO: Handle that a HttpRequest is iterable
19251945
}
19261946
}

python/ql/test/library-tests/frameworks/django-v2-v3/taint_test.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,15 @@ def test_taint(request: HttpRequest, foo, bar, baz=None): # $requestHandler rou
9494
request.resolver_match.kwargs, # $ MISSING: tainted
9595
request.resolver_match.kwargs["key"], # $ MISSING: tainted
9696

97-
request.get_full_path(), # $ MISSING: tainted
98-
request.get_full_path_info(), # $ MISSING: tainted
97+
request.get_full_path(), # $ tainted
98+
request.get_full_path_info(), # $ tainted
9999
# build_absolute_uri handled below
100100
# get_signed_cookie handled below
101101

102-
request.read(), # $ MISSING: tainted
103-
request.readline(), # $ MISSING: tainted
104-
request.readlines(), # $ MISSING: tainted
105-
request.readlines()[0], # $ MISSING: tainted
102+
request.read(), # $ tainted
103+
request.readline(), # $ tainted
104+
request.readlines(), # $ tainted
105+
request.readlines()[0], # $ tainted
106106
[line for line in request], # $ MISSING: tainted
107107
)
108108

@@ -129,9 +129,9 @@ def test_taint(request: HttpRequest, foo, bar, baz=None): # $requestHandler rou
129129
# build_absolute_uri
130130
####################################
131131
ensure_tainted(
132-
request.build_absolute_uri(), # $ MISSING: tainted
133-
request.build_absolute_uri(request.GET["key"]), # $ MISSING: tainted
134-
request.build_absolute_uri(location=request.GET["key"]), # $ MISSING: tainted
132+
request.build_absolute_uri(), # $ tainted
133+
request.build_absolute_uri(request.GET["key"]), # $ tainted
134+
request.build_absolute_uri(location=request.GET["key"]), # $ tainted
135135
)
136136
ensure_not_tainted(
137137
request.build_absolute_uri("/hardcoded/"),

0 commit comments

Comments
 (0)