Skip to content

Commit 5ced5c0

Browse files
Add django header writes
1 parent 7704801 commit 5ced5c0

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2239,6 +2239,37 @@ module PrivateDjango {
22392239

22402240
override DataFlow::Node getValueArg() { result = value }
22412241
}
2242+
2243+
class DjangoResponseHeaderSubscriptWrite extends Http::Server::ResponseHeaderWrite::Range {
2244+
DataFlow::Node index;
2245+
DataFlow::Node value;
2246+
2247+
DjangoResponseHeaderSubscriptWrite() {
2248+
exists(SubscriptNode subscript, DataFlow::AttrRead headerLookup |
2249+
// To give `this` a value, we need to choose between either LHS or RHS,
2250+
// and just go with the LHS
2251+
this.asCfgNode() = subscript
2252+
|
2253+
headerLookup
2254+
.accesses(DjangoImpl::DjangoHttp::Response::HttpResponse::instance(), "headers") and
2255+
exists(DataFlow::Node subscriptObj |
2256+
subscriptObj.asCfgNode() = subscript.getObject()
2257+
|
2258+
headerLookup.flowsTo(subscriptObj)
2259+
) and
2260+
value.asCfgNode() = subscript.(DefinitionNode).getValue() and
2261+
index.asCfgNode() = subscript.getIndex()
2262+
)
2263+
}
2264+
2265+
override DataFlow::Node getNameArg() { result = index }
2266+
2267+
override DataFlow::Node getValueArg() { result = value }
2268+
2269+
override predicate nameAllowsNewline() { none() }
2270+
2271+
override predicate valueAllowsNewline() { none() }
2272+
}
22422273
}
22432274
}
22442275

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def redirect_through_normal_response_new_headers_attr(request):
7272

7373
resp = HttpResponse() # $ HttpResponse mimetype=text/html
7474
resp.status_code = 302
75-
resp.headers['Location'] = next # $ MISSING: redirectLocation=next
75+
resp.headers['Location'] = next # $ headerWriteName='Location' headerWriteValue=next MISSING: redirectLocation=next
7676
resp.content = private # $ MISSING: responseBody=private
7777
return resp
7878

@@ -130,7 +130,7 @@ def setting_cookie(request):
130130
resp = HttpResponse() # $ HttpResponse mimetype=text/html
131131
resp.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value"
132132
resp.set_cookie(key="key", value="value") # $ CookieWrite CookieName="key" CookieValue="value"
133-
resp.headers["Set-Cookie"] = "key2=value2" # $ MISSING: CookieWrite CookieRawHeader="key2=value2"
133+
resp.headers["Set-Cookie"] = "key2=value2" # $ headerWriteName="Set-Cookie" headerWriteValue="key2=value2" CookieWrite CookieRawHeader="key2=value2"
134134
resp.cookies["key3"] = "value3" # $ CookieWrite CookieName="key3" CookieValue="value3"
135135
resp.delete_cookie("key4") # $ CookieWrite CookieName="key4"
136136
resp.delete_cookie(key="key4") # $ CookieWrite CookieName="key4"

0 commit comments

Comments
 (0)