mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Merge pull request #5139 from RasmusWL/django-improvements
Approved by yoff
This commit is contained in:
@@ -1975,6 +1975,14 @@ private module Django {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last decorator call for the function `func`, if `func` has decorators.
|
||||
*/
|
||||
private Expr lastDecoratorCall(Function func) {
|
||||
result = func.getDefinition().(FunctionExpr).getADecoratorCall() and
|
||||
not exists(Call other_decorator | other_decorator.getArg(0) = result)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// routing modeling
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -1987,7 +1995,18 @@ private module Django {
|
||||
*/
|
||||
private DataFlow::Node djangoRouteHandlerFunctionTracker(DataFlow::TypeTracker t, Function func) {
|
||||
t.start() and
|
||||
result = DataFlow::exprNode(func.getDefinition())
|
||||
(
|
||||
not exists(func.getADecorator()) and
|
||||
result.asExpr() = func.getDefinition()
|
||||
or
|
||||
// If the function has decorators, we still want to model the function as being
|
||||
// the request handler for a route setup. In such situations, we must track the
|
||||
// last decorator call instead of the function itself.
|
||||
//
|
||||
// Note that this means that we blindly ignore what the decorator actually does to
|
||||
// the function, which seems like an OK tradeoff.
|
||||
result.asExpr() = lastDecoratorCall(func)
|
||||
)
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 |
|
||||
result = djangoRouteHandlerFunctionTracker(t2, func).track(t2, t)
|
||||
@@ -2005,18 +2024,15 @@ private module Django {
|
||||
result = djangoRouteHandlerFunctionTracker(DataFlow::TypeTracker::end(), func)
|
||||
}
|
||||
|
||||
/** A django View class defined in project code. */
|
||||
class DjangoViewClassDef extends Class {
|
||||
DjangoViewClassDef() { this.getABase() = django::views::generic::View::subclassRef().asExpr() }
|
||||
|
||||
/** Gets a function that could handle incoming requests, if any. */
|
||||
DjangoRouteHandler getARequestHandler() {
|
||||
// TODO: This doesn't handle attribute assignment. Should be OK, but analysis is not as complete as with
|
||||
// points-to and `.lookup`, which would handle `post = my_post_handler` inside class def
|
||||
result = this.getAMethod() and
|
||||
result.getName() = HTTP::httpVerbLower()
|
||||
}
|
||||
|
||||
/**
|
||||
* In order to recognize a class as being a django view class, based on the `as_view`
|
||||
* call, we need to be able to track such calls on _any_ class. This is provided by
|
||||
* the member predicates of this QL class.
|
||||
*
|
||||
* As such, a Python class being part of `DjangoViewClassHelper` doesn't signify that
|
||||
* we model it as a django view class.
|
||||
*/
|
||||
class DjangoViewClassHelper extends Class {
|
||||
/** Gets a reference to this class. */
|
||||
private DataFlow::Node getARef(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
@@ -2051,15 +2067,69 @@ private module Django {
|
||||
DataFlow::Node asViewResult() { result = asViewResult(DataFlow::TypeTracker::end()) }
|
||||
}
|
||||
|
||||
/** A class that we consider a django View class. */
|
||||
abstract class DjangoViewClass extends DjangoViewClassHelper {
|
||||
/** Gets a function that could handle incoming requests, if any. */
|
||||
Function getARequestHandler() {
|
||||
// TODO: This doesn't handle attribute assignment. Should be OK, but analysis is not as complete as with
|
||||
// points-to and `.lookup`, which would handle `post = my_post_handler` inside class def
|
||||
result = this.getAMethod() and
|
||||
result.getName() = HTTP::httpVerbLower()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reference to instances of this class, originating from a self parameter of
|
||||
* a method defined on this class.
|
||||
*
|
||||
* Note: TODO: This doesn't take MRO into account
|
||||
* Note: TODO: This doesn't take staticmethod/classmethod into account
|
||||
*/
|
||||
private DataFlow::Node getASelfRef(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result.(DataFlow::ParameterNode).getParameter() = this.getAMethod().getArg(0)
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = this.getASelfRef(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reference to instances of this class, originating from a self parameter of
|
||||
* a method defined on this class.
|
||||
*
|
||||
* Note: TODO: This doesn't take MRO into account
|
||||
* Note: TODO: This doesn't take staticmethod/classmethod into account
|
||||
*/
|
||||
DataFlow::Node getASelfRef() { result = this.getASelfRef(DataFlow::TypeTracker::end()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A class that is used in a route-setup, with `<class>.as_view()`, therefore being
|
||||
* considered a django View class.
|
||||
*/
|
||||
class DjangoViewClassFromRouteSetup extends DjangoViewClass {
|
||||
DjangoViewClassFromRouteSetup() {
|
||||
exists(DjangoRouteSetup setup | setup.getViewArg() = this.asViewResult())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class that has a super-type which is a django View class, therefore also
|
||||
* becoming a django View class.
|
||||
*/
|
||||
class DjangoViewClassFromSuperClass extends DjangoViewClass {
|
||||
DjangoViewClassFromSuperClass() {
|
||||
this.getABase() = django::views::generic::View::subclassRef().asExpr()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A function that is a django route handler, meaning it handles incoming requests
|
||||
* with the django framework.
|
||||
*/
|
||||
private class DjangoRouteHandler extends Function {
|
||||
DjangoRouteHandler() {
|
||||
exists(djangoRouteHandlerFunctionTracker(this))
|
||||
exists(DjangoRouteSetup route | route.getViewArg() = djangoRouteHandlerFunctionTracker(this))
|
||||
or
|
||||
any(DjangoViewClassDef vc).getARequestHandler() = this
|
||||
any(DjangoViewClass vc).getARequestHandler() = this
|
||||
}
|
||||
|
||||
/** Gets the index of the request parameter. */
|
||||
@@ -2083,7 +2153,7 @@ private module Django {
|
||||
final override DjangoRouteHandler getARequestHandler() {
|
||||
djangoRouteHandlerFunctionTracker(result) = getViewArg()
|
||||
or
|
||||
exists(DjangoViewClassDef vc |
|
||||
exists(DjangoViewClass vc |
|
||||
getViewArg() = vc.asViewResult() and
|
||||
result = vc.getARequestHandler()
|
||||
)
|
||||
@@ -2094,7 +2164,7 @@ private module Django {
|
||||
private class DjangoViewClassHandlerWithoutKnownRoute extends HTTP::Server::RequestHandler::Range,
|
||||
DjangoRouteHandler {
|
||||
DjangoViewClassHandlerWithoutKnownRoute() {
|
||||
exists(DjangoViewClassDef vc | vc.getARequestHandler() = this) and
|
||||
exists(DjangoViewClass vc | vc.getARequestHandler() = this) and
|
||||
not exists(DjangoRouteSetup setup | setup.getARequestHandler() = this)
|
||||
}
|
||||
|
||||
@@ -2267,6 +2337,46 @@ private module Django {
|
||||
override string getSourceType() { result = "django.http.request.HttpRequest" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A read of the `request` attribute on a reference to an instance of a View class,
|
||||
* which is the request being processed currently.
|
||||
*
|
||||
* See https://docs.djangoproject.com/en/3.1/topics/class-based-views/generic-display/#dynamic-filtering
|
||||
*/
|
||||
private class DjangoViewClassRequestAttributeRead extends django::http::request::HttpRequest::InstanceSource,
|
||||
RemoteFlowSource::Range, DataFlow::Node {
|
||||
DjangoViewClassRequestAttributeRead() {
|
||||
exists(DataFlow::AttrRead read | this = read |
|
||||
read.getObject() = any(DjangoViewClass vc).getASelfRef() and
|
||||
read.getAttributeName() = "request"
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() {
|
||||
result = "django.http.request.HttpRequest (attribute on self in View class)"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A read of the `args` or `kwargs` attribute on a reference to an instance of a View class,
|
||||
* which contains the routed parameters captured from the URL route.
|
||||
*
|
||||
* See https://docs.djangoproject.com/en/3.1/topics/class-based-views/generic-display/#dynamic-filtering
|
||||
*/
|
||||
private class DjangoViewClassRoutedParamsAttributeRead extends RemoteFlowSource::Range,
|
||||
DataFlow::Node {
|
||||
DjangoViewClassRoutedParamsAttributeRead() {
|
||||
exists(DataFlow::AttrRead read | this = read |
|
||||
read.getObject() = any(DjangoViewClass vc).getASelfRef() and
|
||||
read.getAttributeName() in ["args", "kwargs"]
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() {
|
||||
result = "django routed param from attribute on self in View class"
|
||||
}
|
||||
}
|
||||
|
||||
private class DjangoHttpRequstAdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
|
||||
override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
nodeFrom = django::http::request::HttpRequest::instance() and
|
||||
|
||||
@@ -1,82 +1,88 @@
|
||||
| taint_test.py:7 | ok | test_taint | bar |
|
||||
| taint_test.py:7 | ok | test_taint | foo |
|
||||
| taint_test.py:8 | ok | test_taint | baz |
|
||||
| taint_test.py:14 | ok | test_taint | request |
|
||||
| taint_test.py:16 | ok | test_taint | request.body |
|
||||
| taint_test.py:17 | ok | test_taint | request.path |
|
||||
| taint_test.py:18 | ok | test_taint | request.path_info |
|
||||
| taint_test.py:22 | ok | test_taint | request.method |
|
||||
| taint_test.py:24 | ok | test_taint | request.encoding |
|
||||
| taint_test.py:25 | ok | test_taint | request.content_type |
|
||||
| taint_test.py:28 | ok | test_taint | request.content_params |
|
||||
| taint_test.py:29 | ok | test_taint | request.content_params["key"] |
|
||||
| taint_test.py:30 | ok | test_taint | request.content_params.get(..) |
|
||||
| taint_test.py:34 | ok | test_taint | request.GET |
|
||||
| taint_test.py:35 | ok | test_taint | request.GET["key"] |
|
||||
| taint_test.py:36 | ok | test_taint | request.GET.get(..) |
|
||||
| taint_test.py:37 | fail | test_taint | request.GET.getlist(..) |
|
||||
| taint_test.py:38 | fail | test_taint | request.GET.getlist(..)[0] |
|
||||
| taint_test.py:39 | ok | test_taint | request.GET.pop(..) |
|
||||
| taint_test.py:40 | ok | test_taint | request.GET.pop(..)[0] |
|
||||
| taint_test.py:41 | ok | test_taint | request.GET.popitem()[0] |
|
||||
| taint_test.py:42 | ok | test_taint | request.GET.popitem()[1] |
|
||||
| taint_test.py:43 | ok | test_taint | request.GET.popitem()[1][0] |
|
||||
| taint_test.py:44 | fail | test_taint | request.GET.dict() |
|
||||
| taint_test.py:45 | fail | test_taint | request.GET.dict()["key"] |
|
||||
| taint_test.py:46 | fail | test_taint | request.GET.urlencode() |
|
||||
| taint_test.py:49 | ok | test_taint | request.POST |
|
||||
| taint_test.py:52 | ok | test_taint | request.COOKIES |
|
||||
| taint_test.py:53 | ok | test_taint | request.COOKIES["key"] |
|
||||
| taint_test.py:54 | ok | test_taint | request.COOKIES.get(..) |
|
||||
| taint_test.py:57 | ok | test_taint | request.FILES |
|
||||
| taint_test.py:58 | ok | test_taint | request.FILES["key"] |
|
||||
| taint_test.py:59 | fail | test_taint | request.FILES["key"].content_type |
|
||||
| taint_test.py:60 | fail | test_taint | request.FILES["key"].content_type_extra |
|
||||
| taint_test.py:61 | fail | test_taint | request.FILES["key"].content_type_extra["key"] |
|
||||
| taint_test.py:62 | fail | test_taint | request.FILES["key"].charset |
|
||||
| taint_test.py:63 | fail | test_taint | request.FILES["key"].name |
|
||||
| taint_test.py:64 | fail | test_taint | request.FILES["key"].file |
|
||||
| taint_test.py:65 | fail | test_taint | request.FILES["key"].file.read() |
|
||||
| taint_test.py:67 | ok | test_taint | request.FILES.get(..) |
|
||||
| taint_test.py:68 | fail | test_taint | request.FILES.get(..).name |
|
||||
| taint_test.py:69 | fail | test_taint | request.FILES.getlist(..) |
|
||||
| taint_test.py:70 | fail | test_taint | request.FILES.getlist(..)[0] |
|
||||
| taint_test.py:71 | fail | test_taint | request.FILES.getlist(..)[0].name |
|
||||
| taint_test.py:72 | fail | test_taint | request.FILES.dict() |
|
||||
| taint_test.py:73 | fail | test_taint | request.FILES.dict()["key"] |
|
||||
| taint_test.py:74 | fail | test_taint | request.FILES.dict()["key"].name |
|
||||
| taint_test.py:77 | ok | test_taint | request.META |
|
||||
| taint_test.py:78 | ok | test_taint | request.META["HTTP_USER_AGENT"] |
|
||||
| taint_test.py:79 | ok | test_taint | request.META.get(..) |
|
||||
| taint_test.py:82 | ok | test_taint | request.headers |
|
||||
| taint_test.py:83 | ok | test_taint | request.headers["user-agent"] |
|
||||
| taint_test.py:84 | ok | test_taint | request.headers["USER_AGENT"] |
|
||||
| taint_test.py:87 | ok | test_taint | request.resolver_match |
|
||||
| taint_test.py:88 | fail | test_taint | request.resolver_match.args |
|
||||
| taint_test.py:89 | fail | test_taint | request.resolver_match.args[0] |
|
||||
| taint_test.py:90 | fail | test_taint | request.resolver_match.kwargs |
|
||||
| taint_test.py:91 | fail | test_taint | request.resolver_match.kwargs["key"] |
|
||||
| taint_test.py:93 | fail | test_taint | request.get_full_path() |
|
||||
| taint_test.py:94 | fail | test_taint | request.get_full_path_info() |
|
||||
| taint_test.py:98 | fail | test_taint | request.read() |
|
||||
| taint_test.py:99 | fail | test_taint | request.readline() |
|
||||
| taint_test.py:100 | fail | test_taint | request.readlines() |
|
||||
| taint_test.py:101 | fail | test_taint | request.readlines()[0] |
|
||||
| taint_test.py:102 | fail | test_taint | ListComp |
|
||||
| taint_test.py:108 | ok | test_taint | args |
|
||||
| taint_test.py:109 | ok | test_taint | args[0] |
|
||||
| taint_test.py:110 | ok | test_taint | kwargs |
|
||||
| taint_test.py:111 | ok | test_taint | kwargs["key"] |
|
||||
| taint_test.py:115 | ok | test_taint | request.current_app |
|
||||
| taint_test.py:120 | ok | test_taint | request.get_host() |
|
||||
| taint_test.py:121 | ok | test_taint | request.get_port() |
|
||||
| taint_test.py:128 | fail | test_taint | request.build_absolute_uri() |
|
||||
| taint_test.py:129 | fail | test_taint | request.build_absolute_uri(..) |
|
||||
| taint_test.py:8 | ok | test_taint | bar |
|
||||
| taint_test.py:8 | ok | test_taint | foo |
|
||||
| taint_test.py:9 | ok | test_taint | baz |
|
||||
| taint_test.py:15 | ok | test_taint | request |
|
||||
| taint_test.py:17 | ok | test_taint | request.body |
|
||||
| taint_test.py:18 | ok | test_taint | request.path |
|
||||
| taint_test.py:19 | ok | test_taint | request.path_info |
|
||||
| taint_test.py:23 | ok | test_taint | request.method |
|
||||
| taint_test.py:25 | ok | test_taint | request.encoding |
|
||||
| taint_test.py:26 | ok | test_taint | request.content_type |
|
||||
| taint_test.py:29 | ok | test_taint | request.content_params |
|
||||
| taint_test.py:30 | ok | test_taint | request.content_params["key"] |
|
||||
| taint_test.py:31 | ok | test_taint | request.content_params.get(..) |
|
||||
| taint_test.py:35 | ok | test_taint | request.GET |
|
||||
| taint_test.py:36 | ok | test_taint | request.GET["key"] |
|
||||
| taint_test.py:37 | ok | test_taint | request.GET.get(..) |
|
||||
| taint_test.py:38 | fail | test_taint | request.GET.getlist(..) |
|
||||
| taint_test.py:39 | fail | test_taint | request.GET.getlist(..)[0] |
|
||||
| taint_test.py:40 | ok | test_taint | request.GET.pop(..) |
|
||||
| taint_test.py:41 | ok | test_taint | request.GET.pop(..)[0] |
|
||||
| taint_test.py:42 | ok | test_taint | request.GET.popitem()[0] |
|
||||
| taint_test.py:43 | ok | test_taint | request.GET.popitem()[1] |
|
||||
| taint_test.py:44 | ok | test_taint | request.GET.popitem()[1][0] |
|
||||
| taint_test.py:45 | fail | test_taint | request.GET.dict() |
|
||||
| taint_test.py:46 | fail | test_taint | request.GET.dict()["key"] |
|
||||
| taint_test.py:47 | fail | test_taint | request.GET.urlencode() |
|
||||
| taint_test.py:50 | ok | test_taint | request.POST |
|
||||
| taint_test.py:53 | ok | test_taint | request.COOKIES |
|
||||
| taint_test.py:54 | ok | test_taint | request.COOKIES["key"] |
|
||||
| taint_test.py:55 | ok | test_taint | request.COOKIES.get(..) |
|
||||
| taint_test.py:58 | ok | test_taint | request.FILES |
|
||||
| taint_test.py:59 | ok | test_taint | request.FILES["key"] |
|
||||
| taint_test.py:60 | fail | test_taint | request.FILES["key"].content_type |
|
||||
| taint_test.py:61 | fail | test_taint | request.FILES["key"].content_type_extra |
|
||||
| taint_test.py:62 | fail | test_taint | request.FILES["key"].content_type_extra["key"] |
|
||||
| taint_test.py:63 | fail | test_taint | request.FILES["key"].charset |
|
||||
| taint_test.py:64 | fail | test_taint | request.FILES["key"].name |
|
||||
| taint_test.py:65 | fail | test_taint | request.FILES["key"].file |
|
||||
| taint_test.py:66 | fail | test_taint | request.FILES["key"].file.read() |
|
||||
| taint_test.py:68 | ok | test_taint | request.FILES.get(..) |
|
||||
| taint_test.py:69 | fail | test_taint | request.FILES.get(..).name |
|
||||
| taint_test.py:70 | fail | test_taint | request.FILES.getlist(..) |
|
||||
| taint_test.py:71 | fail | test_taint | request.FILES.getlist(..)[0] |
|
||||
| taint_test.py:72 | fail | test_taint | request.FILES.getlist(..)[0].name |
|
||||
| taint_test.py:73 | fail | test_taint | request.FILES.dict() |
|
||||
| taint_test.py:74 | fail | test_taint | request.FILES.dict()["key"] |
|
||||
| taint_test.py:75 | fail | test_taint | request.FILES.dict()["key"].name |
|
||||
| taint_test.py:78 | ok | test_taint | request.META |
|
||||
| taint_test.py:79 | ok | test_taint | request.META["HTTP_USER_AGENT"] |
|
||||
| taint_test.py:80 | ok | test_taint | request.META.get(..) |
|
||||
| taint_test.py:83 | ok | test_taint | request.headers |
|
||||
| taint_test.py:84 | ok | test_taint | request.headers["user-agent"] |
|
||||
| taint_test.py:85 | ok | test_taint | request.headers["USER_AGENT"] |
|
||||
| taint_test.py:88 | ok | test_taint | request.resolver_match |
|
||||
| taint_test.py:89 | fail | test_taint | request.resolver_match.args |
|
||||
| taint_test.py:90 | fail | test_taint | request.resolver_match.args[0] |
|
||||
| taint_test.py:91 | fail | test_taint | request.resolver_match.kwargs |
|
||||
| taint_test.py:92 | fail | test_taint | request.resolver_match.kwargs["key"] |
|
||||
| taint_test.py:94 | fail | test_taint | request.get_full_path() |
|
||||
| taint_test.py:95 | fail | test_taint | request.get_full_path_info() |
|
||||
| taint_test.py:99 | fail | test_taint | request.read() |
|
||||
| taint_test.py:100 | fail | test_taint | request.readline() |
|
||||
| taint_test.py:101 | fail | test_taint | request.readlines() |
|
||||
| taint_test.py:102 | fail | test_taint | request.readlines()[0] |
|
||||
| taint_test.py:103 | fail | test_taint | ListComp |
|
||||
| taint_test.py:109 | ok | test_taint | args |
|
||||
| taint_test.py:110 | ok | test_taint | args[0] |
|
||||
| taint_test.py:111 | ok | test_taint | kwargs |
|
||||
| taint_test.py:112 | ok | test_taint | kwargs["key"] |
|
||||
| taint_test.py:116 | ok | test_taint | request.current_app |
|
||||
| taint_test.py:121 | ok | test_taint | request.get_host() |
|
||||
| taint_test.py:122 | ok | test_taint | request.get_port() |
|
||||
| taint_test.py:129 | fail | test_taint | request.build_absolute_uri() |
|
||||
| taint_test.py:130 | fail | test_taint | request.build_absolute_uri(..) |
|
||||
| taint_test.py:133 | ok | test_taint | request.build_absolute_uri(..) |
|
||||
| taint_test.py:131 | fail | test_taint | request.build_absolute_uri(..) |
|
||||
| taint_test.py:134 | ok | test_taint | request.build_absolute_uri(..) |
|
||||
| taint_test.py:142 | ok | test_taint | request.get_signed_cookie(..) |
|
||||
| taint_test.py:135 | ok | test_taint | request.build_absolute_uri(..) |
|
||||
| taint_test.py:143 | ok | test_taint | request.get_signed_cookie(..) |
|
||||
| taint_test.py:144 | ok | test_taint | request.get_signed_cookie(..) |
|
||||
| taint_test.py:148 | fail | test_taint | request.get_signed_cookie(..) |
|
||||
| taint_test.py:145 | ok | test_taint | request.get_signed_cookie(..) |
|
||||
| taint_test.py:149 | fail | test_taint | request.get_signed_cookie(..) |
|
||||
| taint_test.py:150 | fail | test_taint | request.get_signed_cookie(..) |
|
||||
| taint_test.py:157 | ok | some_method | self.request |
|
||||
| taint_test.py:158 | ok | some_method | self.request.GET["key"] |
|
||||
| taint_test.py:160 | ok | some_method | self.args |
|
||||
| taint_test.py:161 | ok | some_method | self.args[0] |
|
||||
| taint_test.py:163 | ok | some_method | self.kwargs |
|
||||
| taint_test.py:164 | ok | some_method | self.kwargs["key"] |
|
||||
|
||||
@@ -3,6 +3,7 @@ from django.urls import path, re_path
|
||||
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse, HttpResponseNotFound
|
||||
from django.views import View
|
||||
import django.views.generic.base
|
||||
from django.views.decorators.http import require_GET
|
||||
|
||||
|
||||
def url_match_xss(request, foo, bar, no_taint=None): # $requestHandler routedParameter=foo routedParameter=bar
|
||||
@@ -105,6 +106,10 @@ urlpatterns = [
|
||||
path("not_valid/<not_valid!>", not_valid_identifier), # $routeSetup="not_valid/<not_valid!>"
|
||||
]
|
||||
|
||||
################################################################################
|
||||
# Deprecated django.conf.urls.url
|
||||
################################################################################
|
||||
|
||||
# This version 1.x way of defining urls is deprecated in Django 3.1, but still works
|
||||
from django.conf.urls import url
|
||||
|
||||
@@ -116,9 +121,32 @@ urlpatterns = [
|
||||
]
|
||||
|
||||
|
||||
################################################################################
|
||||
# Special stuff
|
||||
################################################################################
|
||||
|
||||
class PossiblyNotRouted(View):
|
||||
# Even if our analysis can't find a route-setup for this class, we should still
|
||||
# consider it to be a handle incoming HTTP requests
|
||||
|
||||
def get(self, request, possibly_not_routed=42): # $ requestHandler routedParameter=possibly_not_routed
|
||||
return HttpResponse('PossiblyNotRouted get: {}'.format(possibly_not_routed)) # $HttpResponse
|
||||
|
||||
|
||||
@require_GET
|
||||
def with_decorator(request, foo): # $ requestHandler routedParameter=foo
|
||||
pass
|
||||
|
||||
urlpatterns = [
|
||||
path("with_decorator/<foo>", with_decorator), # $ routeSetup="with_decorator/<foo>"
|
||||
]
|
||||
|
||||
class UnknownViewSubclass(UnknownViewSuperclass):
|
||||
# Although we don't know for certain that this class is a django view class, the fact that it's
|
||||
# used with `as_view()` in the routing setup should be enough that we treat it as such.
|
||||
def get(self, request): # $ requestHandler
|
||||
pass
|
||||
|
||||
urlpatterns = [
|
||||
path("UnknownViewSubclass/", UnknownViewSubclass.as_view()), # $ routeSetup="UnknownViewSubclass/"
|
||||
]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""testing views for Django 2.x and 3.x"""
|
||||
from django.urls import path
|
||||
from django.http import HttpRequest
|
||||
from django.views import View
|
||||
|
||||
|
||||
def test_taint(request: HttpRequest, foo, bar, baz=None): # $requestHandler routedParameter=foo routedParameter=bar
|
||||
@@ -150,7 +151,22 @@ def test_taint(request: HttpRequest, foo, bar, baz=None): # $requestHandler rou
|
||||
)
|
||||
|
||||
|
||||
class ClassView(View):
|
||||
def some_method(self):
|
||||
ensure_tainted(
|
||||
self.request,
|
||||
self.request.GET["key"],
|
||||
|
||||
self.args,
|
||||
self.args[0],
|
||||
|
||||
self.kwargs,
|
||||
self.kwargs["key"],
|
||||
)
|
||||
|
||||
|
||||
# fake setup, you can't actually run this
|
||||
urlpatterns = [
|
||||
path("test-taint/<foo>/<bar>", test_taint), # $routeSetup="test-taint/<foo>/<bar>"
|
||||
path("test-taint/<foo>/<bar>", test_taint), # $ routeSetup="test-taint/<foo>/<bar>"
|
||||
path("ClassView/", ClassView.as_view()), # $ routeSetup="ClassView/"
|
||||
]
|
||||
|
||||
@@ -30,4 +30,5 @@ class MyCustomViewBaseClass(View):
|
||||
|
||||
class MyViewHandlerWithCustomInheritance(MyCustomViewBaseClass):
|
||||
def get(self, request: HttpRequest): # $ requestHandler
|
||||
print(self.request.GET)
|
||||
return HttpResponse("MyViewHandlerWithCustomInheritance: GET") # $ HttpResponse
|
||||
|
||||
Reference in New Issue
Block a user