Python: Identify route handlers for django

Not including class based handlers
This commit is contained in:
Rasmus Wriedt Larsen
2020-10-15 19:42:15 +02:00
parent c0d71f767a
commit 44683f2959
3 changed files with 55 additions and 24 deletions

View File

@@ -133,10 +133,42 @@ private module Django {
}
}
private class DjangoPathRouteSetup extends HTTP::Server::RouteSetup::Range, DataFlow::CfgNode {
/**
* Gets a reference to the Function `func`.
*
* The idea is that this function should be used as a route handler when setting up a
* route, but currently it just tracks all functions, since we can't do type-tracking
* backwards yet (TODO).
*/
private DataFlow::Node djangoRouteHandlerFunctionTracker(DataFlow::TypeTracker t, Function func) {
t.start() and
result = DataFlow::exprNode(func.getDefinition())
or
exists(DataFlow::TypeTracker t2 |
result = djangoRouteHandlerFunctionTracker(t2, func).track(t2, t)
)
}
/**
* Gets a reference to the Function `func`.
*
* The idea is that this function should be used as a route handler when setting up a
* route, but currently it just tracks all functions, since we can't do type-tracking
* backwards yet (TODO).
*/
private DataFlow::Node djangoRouteHandlerFunctionTracker(Function func) {
result = djangoRouteHandlerFunctionTracker(DataFlow::TypeTracker::end(), func)
}
/**
* A call to `django.urls.path`.
*
* See https://docs.djangoproject.com/en/3.0/ref/urls/#path
*/
private class DjangoUrlsPathCall extends HTTP::Server::RouteSetup::Range, DataFlow::CfgNode {
override CallNode node;
DjangoPathRouteSetup() { node.getFunction() = django::urls::path().asCfgNode() }
DjangoUrlsPathCall() { node.getFunction() = django::urls::path().asCfgNode() }
override string getUrlPattern() {
exists(StrConst str, ControlFlowNode urlPatternArg |
@@ -148,15 +180,25 @@ private module Django {
)
}
override Function getARouteHandler() { none() }
override Function getARouteHandler() {
exists(DataFlow::Node viewArg |
viewArg.asCfgNode() in [node.getArg(1), node.getArgByName("view")] and
djangoRouteHandlerFunctionTracker(result) = viewArg
)
}
override Parameter getARoutedParameter() { none() }
}
private class DjangoRePathRouteSetup extends HTTP::Server::RouteSetup::Range, DataFlow::CfgNode {
/**
* A call to `django.urls.re_path`.
*
* See https://docs.djangoproject.com/en/3.0/ref/urls/#re_path
*/
private class DjangoUrlsRePathCall extends HTTP::Server::RouteSetup::Range, DataFlow::CfgNode {
override CallNode node;
DjangoRePathRouteSetup() { node.getFunction() = django::urls::re_path().asCfgNode() }
DjangoUrlsRePathCall() { node.getFunction() = django::urls::re_path().asCfgNode() }
override string getUrlPattern() {
exists(StrConst str, ControlFlowNode urlPatternArg |
@@ -168,7 +210,12 @@ private module Django {
)
}
override Function getARouteHandler() { none() }
override Function getARouteHandler() {
exists(DataFlow::Node viewArg |
viewArg.asCfgNode() in [node.getArg(1), node.getArgByName("view")] and
djangoRouteHandlerFunctionTracker(result) = viewArg
)
}
override Parameter getARoutedParameter() { none() }
}

View File

@@ -1,30 +1,14 @@
| routing_test.py:7:55:7:111 | Comment # $routeHandler $routedParameter=foo $routedParameter=bar | Missing result:routeHandler= |
| routing_test.py:7:55:7:111 | Comment # $routeHandler $routedParameter=foo $routedParameter=bar | Missing result:routedParameter=bar |
| routing_test.py:7:55:7:111 | Comment # $routeHandler $routedParameter=foo $routedParameter=bar | Missing result:routedParameter=foo |
| routing_test.py:11:31:11:45 | Comment # $routeHandler | Missing result:routeHandler= |
| routing_test.py:15:32:15:46 | Comment # $routeHandler | Missing result:routeHandler= |
| routing_test.py:19:32:19:46 | Comment # $routeHandler | Missing result:routeHandler= |
| routing_test.py:29:42:29:83 | Comment # $routeHandler $routedParameter=untrusted | Missing result:routeHandler= |
| routing_test.py:29:42:29:83 | Comment # $routeHandler $routedParameter=untrusted | Missing result:routedParameter=untrusted |
| routing_test.py:35:41:35:82 | Comment # $routeHandler $routedParameter=untrusted | Missing result:routeHandler= |
| routing_test.py:35:41:35:82 | Comment # $routeHandler $routedParameter=untrusted | Missing result:routedParameter=untrusted |
| routing_test.py:39:45:39:88 | Comment # $routeHandler $routedParameter=page_number | Missing result:routeHandler= |
| routing_test.py:39:45:39:88 | Comment # $routeHandler $routedParameter=page_number | Missing result:routedParameter=page_number |
| routing_test.py:44:62:44:120 | Comment # $routeHandler $routedParameter=arg0 $routedParameter=arg1 | Missing result:routeHandler= |
| routing_test.py:44:62:44:120 | Comment # $routeHandler $routedParameter=arg0 $routedParameter=arg1 | Missing result:routedParameter=arg0 |
| routing_test.py:44:62:44:120 | Comment # $routeHandler $routedParameter=arg0 $routedParameter=arg1 | Missing result:routedParameter=arg1 |
| routing_test.py:65:31:65:45 | Comment # $routeHandler | Missing result:routeHandler= |
| routing_test.py:78:43:78:86 | Comment # $routeHandler $routedParameter=page_number | Missing result:routeHandler= |
| routing_test.py:78:43:78:86 | Comment # $routeHandler $routedParameter=page_number | Missing result:routedParameter=page_number |
| routing_test.py:81:43:81:120 | Comment # $routeHandler $routedParameter=foo $routedParameter=bar $routedParameter=baz | Missing result:routeHandler= |
| routing_test.py:81:43:81:120 | Comment # $routeHandler $routedParameter=foo $routedParameter=bar $routedParameter=baz | Missing result:routedParameter=bar |
| routing_test.py:81:43:81:120 | Comment # $routeHandler $routedParameter=foo $routedParameter=bar $routedParameter=baz | Missing result:routedParameter=baz |
| routing_test.py:81:43:81:120 | Comment # $routeHandler $routedParameter=foo $routedParameter=bar $routedParameter=baz | Missing result:routedParameter=foo |
| routing_test.py:84:38:84:94 | Comment # $routeHandler $routedParameter=foo $routedParameter=bar | Missing result:routeHandler= |
| routing_test.py:84:38:84:94 | Comment # $routeHandler $routedParameter=foo $routedParameter=bar | Missing result:routedParameter=bar |
| routing_test.py:84:38:84:94 | Comment # $routeHandler $routedParameter=foo $routedParameter=bar | Missing result:routedParameter=foo |
| routing_test.py:87:37:87:51 | Comment # $routeHandler | Missing result:routeHandler= |
| taint_test.py:6:60:6:116 | Comment # $routeHandler $routedParameter=foo $routedParameter=bar | Missing result:routeHandler= |
| taint_test.py:6:60:6:116 | Comment # $routeHandler $routedParameter=foo $routedParameter=bar | Missing result:routedParameter=bar |
| taint_test.py:6:60:6:116 | Comment # $routeHandler $routedParameter=foo $routedParameter=bar | Missing result:routedParameter=foo |
| testapp/views.py:3:33:3:47 | Comment # $routeHandler | Missing result:routeHandler= |

View File

@@ -26,13 +26,13 @@ class Foo(object):
# Note: since Foo is used as the super type in a class view, it will be able to handle requests.
def post(self, request, untrusted): # $routeHandler $routedParameter=untrusted
def post(self, request, untrusted): # $f-:routeHandler $f-:routedParameter=untrusted
return HttpResponse('Foo post: {}'.format(untrusted))
class ClassView(View, Foo):
def get(self, request, untrusted): # $routeHandler $routedParameter=untrusted
def get(self, request, untrusted): # $f-:routeHandler $f-:routedParameter=untrusted
return HttpResponse('ClassView get: {}'.format(untrusted))