mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Python: Add rest_framework Response modeling
This commit is contained in:
@@ -259,4 +259,44 @@ private module RestFramework {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// response modeling
|
||||
// ---------------------------------------------------------------------------
|
||||
/**
|
||||
* Provides models for the `rest_framework.response.Response` class
|
||||
*
|
||||
* See https://www.django-rest-framework.org/api-guide/responses/.
|
||||
*/
|
||||
module Response {
|
||||
/** Gets a reference to the `rest_framework.response.Response` class. */
|
||||
private API::Node classRef() {
|
||||
result = API::moduleImport("rest_framework").getMember("response").getMember("Response")
|
||||
}
|
||||
|
||||
/**
|
||||
* A source of instances of `rest_framework.response.Response`, extend this class to model new instances.
|
||||
*
|
||||
* This can include instantiations of the class, return values from function
|
||||
* calls, or a special parameter that will be set when functions are called by an external
|
||||
* library.
|
||||
*
|
||||
* Use the predicate `Response::instance()` to get references to instances of `rest_framework.response.Response`.
|
||||
*/
|
||||
abstract class InstanceSource extends DataFlow::LocalSourceNode { }
|
||||
|
||||
/** A direct instantiation of `rest_framework.response.Response`. */
|
||||
private class ClassInstantiation extends PrivateDjango::django::http::response::HttpResponse::InstanceSource,
|
||||
DataFlow::CallCfgNode {
|
||||
ClassInstantiation() { this = classRef().getACall() }
|
||||
|
||||
override DataFlow::Node getBody() { result in [this.getArg(0), this.getArgByName("data")] }
|
||||
|
||||
override DataFlow::Node getMimetypeOrContentTypeArg() {
|
||||
result in [this.getArg(5), this.getArgByName("content_type")]
|
||||
}
|
||||
|
||||
override string getMimetypeDefault() { none() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
from rest_framework.decorators import api_view
|
||||
from rest_framework.response import Response
|
||||
|
||||
@api_view()
|
||||
def normal_response(request): # $ requestHandler
|
||||
# has no pre-defined content type, since that will be negotiated
|
||||
# see https://www.django-rest-framework.org/api-guide/responses/
|
||||
data = "data"
|
||||
resp = Response(data) # $ HttpResponse responseBody=data
|
||||
return resp
|
||||
|
||||
@api_view()
|
||||
def plain_text_response(request): # $ requestHandler
|
||||
# this response is not the standard way to use the Djagno REST framework, but it
|
||||
# certainly is possible -- notice that the response contains double quotes
|
||||
data = 'this response will contain double quotes since it was a string'
|
||||
resp = Response(data, None, None, None, None, "text/plain") # $ HttpResponse mimetype=text/plain responseBody=data
|
||||
resp = Response(data=data, content_type="text/plain") # $ HttpResponse mimetype=text/plain responseBody=data
|
||||
return resp
|
||||
|
||||
################################################################################
|
||||
# Cookies
|
||||
################################################################################
|
||||
|
||||
@api_view
|
||||
def setting_cookie(request):
|
||||
resp = Response() # $ HttpResponse
|
||||
resp.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value"
|
||||
resp.set_cookie(key="key4", value="value") # $ CookieWrite CookieName="key4" CookieValue="value"
|
||||
resp.headers["Set-Cookie"] = "key2=value2" # $ MISSING: CookieWrite CookieRawHeader="key2=value2"
|
||||
resp.cookies["key3"] = "value3" # $ CookieWrite CookieName="key3" CookieValue="value3"
|
||||
resp.delete_cookie("key4") # $ CookieWrite CookieName="key4"
|
||||
resp.delete_cookie(key="key4") # $ CookieWrite CookieName="key4"
|
||||
return resp
|
||||
@@ -81,7 +81,7 @@ def test_taint(request: Request, routed_param): # $ requestHandler routedParamet
|
||||
)
|
||||
ensure_not_tainted(request.user.password)
|
||||
|
||||
return Response("ok")
|
||||
return Response("ok") # $ HttpResponse responseBody="ok"
|
||||
|
||||
|
||||
# class based view
|
||||
@@ -105,7 +105,7 @@ class MyClass(APIView):
|
||||
# same as for standard Django view
|
||||
ensure_tainted(self.args, self.kwargs) # $ tainted
|
||||
|
||||
return Response("ok")
|
||||
return Response("ok") # $ HttpResponse responseBody="ok"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -13,4 +13,5 @@ urlpatterns = [
|
||||
path("api-auth/", include("rest_framework.urls", namespace="rest_framework")),
|
||||
path("class-based-view/", views.MyClass.as_view()), # $routeSetup="lcass-based-view/"
|
||||
path("function-based-view/", views.function_based_view), # $routeSetup="function-based-view/"
|
||||
path("cookie-test/", views.cookie_test), # $routeSetup="function-based-view/"
|
||||
]
|
||||
|
||||
@@ -40,3 +40,13 @@ class MyClass(APIView):
|
||||
@api_view(["GET", "POST"])
|
||||
def function_based_view(request: Request):
|
||||
return Response({"message": "Hello, world!"})
|
||||
|
||||
|
||||
@api_view(["GET", "POST"])
|
||||
def cookie_test(request: Request):
|
||||
resp = Response("wat")
|
||||
resp.set_cookie("key", "value") # $ CookieWrite CookieName="key" CookieValue="value"
|
||||
resp.set_cookie(key="key4", value="value") # $ CookieWrite CookieName="key" CookieValue="value"
|
||||
resp.headers["Set-Cookie"] = "key2=value2" # $ MISSING: CookieWrite CookieRawHeader="key2=value2"
|
||||
resp.cookies["key3"] = "value3" # $ CookieWrite CookieName="key3" CookieValue="value3"
|
||||
return resp
|
||||
|
||||
Reference in New Issue
Block a user