Python: Add redirect modeling for Django

This commit is contained in:
Rasmus Wriedt Larsen
2021-01-19 14:45:41 +01:00
parent aea974ee0c
commit ab607b8030
2 changed files with 16 additions and 6 deletions

View File

@@ -724,7 +724,8 @@ private module Django {
*
* Use the predicate `HttpResponseRedirect::instance()` to get references to instances of `django.http.response.HttpResponseRedirect`.
*/
abstract class InstanceSource extends HttpResponse::InstanceSource, DataFlow::Node { }
abstract class InstanceSource extends HttpResponse::InstanceSource,
HTTP::Server::HttpRedirectResponse::Range, DataFlow::Node { }
/** A direct instantiation of `django.http.response.HttpResponseRedirect`. */
private class ClassInstantiation extends InstanceSource, DataFlow::CfgNode {
@@ -739,6 +740,10 @@ private module Django {
result.asCfgNode() in [node.getArg(1), node.getArgByName("content")]
}
override DataFlow::Node getRedirectLocation() {
result.asCfgNode() in [node.getArg(0), node.getArgByName("redirect_to")]
}
// How to support the `headers` argument here?
override DataFlow::Node getMimetypeOrContentTypeArg() { none() }
@@ -790,7 +795,8 @@ private module Django {
*
* Use the predicate `HttpResponsePermanentRedirect::instance()` to get references to instances of `django.http.response.HttpResponsePermanentRedirect`.
*/
abstract class InstanceSource extends HttpResponse::InstanceSource, DataFlow::Node { }
abstract class InstanceSource extends HttpResponse::InstanceSource,
HTTP::Server::HttpRedirectResponse::Range, DataFlow::Node { }
/** A direct instantiation of `django.http.response.HttpResponsePermanentRedirect`. */
private class ClassInstantiation extends InstanceSource, DataFlow::CfgNode {
@@ -805,6 +811,10 @@ private module Django {
result.asCfgNode() in [node.getArg(1), node.getArgByName("content")]
}
override DataFlow::Node getRedirectLocation() {
result.asCfgNode() in [node.getArg(0), node.getArgByName("redirect_to")]
}
// How to support the `headers` argument here?
override DataFlow::Node getMimetypeOrContentTypeArg() { none() }

View File

@@ -19,22 +19,22 @@ def safe__manual_content_type(request):
# Note: This should be an open-redirect sink, but not an XSS sink.
def or__redirect(request):
next = request.GET.get("next")
return HttpResponseRedirect(next) # $HttpResponse mimetype=text/html MISSING: HttpRedirectResponse redirectLocation=next
return HttpResponseRedirect(next) # $HttpResponse mimetype=text/html HttpRedirectResponse redirectLocation=next
def information_exposure_through_redirect(request, as_kw=False, perm_redirect=False):
# This is a contrived example, but possible
private = "private"
next = request.GET.get("next")
if as_kw:
return HttpResponseRedirect(next, content=private) # $HttpResponse mimetype=text/html responseBody=private MISSING: HttpRedirectResponse redirectLocation=next
return HttpResponseRedirect(next, content=private) # $HttpResponse mimetype=text/html responseBody=private HttpRedirectResponse redirectLocation=next
else:
return HttpResponseRedirect(next, private) # $ HttpResponse mimetype=text/html responseBody=private MISSING: HttpRedirectResponse redirectLocation=next
return HttpResponseRedirect(next, private) # $ HttpResponse mimetype=text/html responseBody=private HttpRedirectResponse redirectLocation=next
def perm_redirect(request):
private = "private"
next = request.GET.get("next")
return HttpResponsePermanentRedirect(next, private) # $ HttpResponse mimetype=text/html responseBody=private MISSING: HttpRedirectResponse redirectLocation=next
return HttpResponsePermanentRedirect(next, private) # $ HttpResponse mimetype=text/html responseBody=private HttpRedirectResponse redirectLocation=next
def redirect_through_normal_response(request):