Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e693497

Browse files
Rasmus Lerchedahl PetersenRasmus Lerchedahl Petersen
authored andcommitted
Python: django.http.response.HttpRequest.write
1 parent ffe10d1 commit e693497

3 files changed

Lines changed: 41 additions & 3 deletions

File tree

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,44 @@ private module Django {
14951495
/** Gets a reference to an instance of `django.http.response.FileResponse`. */
14961496
DataFlow::Node instance() { result = instance(DataFlow::TypeTracker::end()) }
14971497
}
1498+
1499+
/** Gets a reference to the `django.http.response.HttpResponse.write` function. */
1500+
private DataFlow::Node write(
1501+
django::http::response::HttpResponse::InstanceSource instance, DataFlow::TypeTracker t
1502+
) {
1503+
t.startInAttr("write") and
1504+
instance = django::http::response::HttpResponse::instance() and
1505+
result = instance
1506+
or
1507+
exists(DataFlow::TypeTracker t2 | result = write(instance, t2).track(t2, t))
1508+
}
1509+
1510+
/** Gets a reference to the `django.http.response.HttpResponse.write` function. */
1511+
DataFlow::Node write(django::http::response::HttpResponse::InstanceSource instance) {
1512+
result = write(instance, DataFlow::TypeTracker::end())
1513+
}
1514+
1515+
/**
1516+
* A call to the `django.http.response.HttpResponse.write` function.
1517+
*
1518+
* See https://docs.djangoproject.com/en/3.1/ref/request-response/#django.http.HttpResponse.write
1519+
*/
1520+
class HttpResponseWriteCall extends HTTP::Server::HttpResponse::Range, DataFlow::CfgNode {
1521+
override CallNode node;
1522+
HTTP::Server::HttpResponse::Range instance;
1523+
1524+
HttpResponseWriteCall() { node.getFunction() = write(instance).asCfgNode() }
1525+
1526+
override DataFlow::Node getBody() {
1527+
result.asCfgNode() in [node.getArg(0), node.getArgByName("content")]
1528+
}
1529+
1530+
override DataFlow::Node getMimetypeOrContentTypeArg() {
1531+
result = instance.getMimetypeOrContentTypeArg()
1532+
}
1533+
1534+
override string getMimetypeDefault() { result = instance.getMimetypeDefault() }
1535+
}
14981536
}
14991537
}
15001538
}

python/ql/test/experimental/library-tests/frameworks/django-v1/response_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ def xss__manual_response_type(request):
3030

3131
def xss__write(request):
3232
response = HttpResponse() # $HttpResponse $mimetype=text/html; charset=utf-8
33-
response.write(request.GET.get("name")) # $f-:HttpResponse $f-:mimetype=text/html; charset=utf-8 $f-:responseBody=Attribute()
33+
response.write(request.GET.get("name")) # $HttpResponse $mimetype=text/html; charset=utf-8 $responseBody=Attribute()
3434

3535
# This is safe but probably a bug if the argument to `write` is not a result of `json.dumps` or similar.
3636
def safe__write_json(request):
3737
response = JsonResponse() # $HttpResponse $mimetype=application/json
38-
response.write(request.GET.get("name")) # $f-:HttpResponse $f-:mimetype=application/json $f-:responseBody=Attribute()
38+
response.write(request.GET.get("name")) # $HttpResponse $mimetype=application/json $responseBody=Attribute()
3939

4040
# Ensure manual subclasses are vulnerable
4141
class CustomResponse(HttpResponse):

python/ql/test/experimental/library-tests/frameworks/django-v1/routing_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def post_params_xss(request): # $routeHandler
1818

1919
def http_resp_write(request): # $routeHandler
2020
rsp = HttpResponse() # $HttpResponse
21-
rsp.write(request.GET.get("untrusted"))
21+
rsp.write(request.GET.get("untrusted")) # $HttpResponse
2222
return rsp
2323

2424

0 commit comments

Comments
 (0)