Python: Model tainted attributes of django HttpRequest

This commit is contained in:
Rasmus Wriedt Larsen
2020-10-16 11:05:45 +02:00
parent a3cdbf2052
commit 86798063a3
2 changed files with 65 additions and 36 deletions

View File

@@ -6,8 +6,9 @@
private import python
private import experimental.dataflow.DataFlow
private import experimental.dataflow.RemoteFlowSources
private import experimental.dataflow.TaintTracking
private import experimental.semmle.python.Concepts
import semmle.python.regex
private import semmle.python.regex
/**
* Provides models for the `django` PyPI package.
@@ -455,4 +456,32 @@ private module Django {
override string getSourceType() { result = "django.http.request.HttpRequest" }
}
private class DjangoHttpRequstAdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
nodeFrom = django::http::request::HttpRequest::instance() and
exists(DataFlow::AttrRead read | nodeTo = read and read.getObject() = nodeFrom |
read.getAttributeName() in ["body",
// str / bytes
"path", "path_info", "method", "encoding", "content_type",
// django.http.QueryDict
// TODO: Model QueryDict
"GET", "POST",
// dict[str, str]
"content_params", "COOKIES",
// dict[str, Any]
"META",
// HttpHeaders (case insensitive dict-like)
"headers",
// MultiValueDict[str, UploadedFile]
// TODO: Model MultiValueDict
// TODO: Model UploadedFile
"FILES",
// django.urls.ResolverMatch
// TODO: Model ResolverMatch
"resolver_match"]
// TODO: Handle calls to methods
// TODO: Handle that a HttpRequest is iterable
)
}
}
}

View File

@@ -2,34 +2,34 @@
| 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 | fail | test_taint | request.body |
| taint_test.py:17 | fail | test_taint | request.path |
| taint_test.py:18 | fail | test_taint | request.path_info |
| taint_test.py:22 | fail | test_taint | request.method |
| taint_test.py:24 | fail | test_taint | request.encoding |
| taint_test.py:25 | fail | test_taint | request.content_type |
| taint_test.py:28 | fail | test_taint | request.content_params |
| taint_test.py:29 | fail | test_taint | request.content_params["key"] |
| taint_test.py:30 | fail | test_taint | request.content_params.get(..) |
| taint_test.py:34 | fail | test_taint | request.GET |
| taint_test.py:35 | fail | test_taint | request.GET["key"] |
| taint_test.py:36 | fail | test_taint | request.GET.get(..) |
| 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 | fail | test_taint | request.GET.pop(..) |
| taint_test.py:40 | fail | test_taint | request.GET.pop(..)[0] |
| taint_test.py:41 | fail | test_taint | request.GET.popitem()[0] |
| taint_test.py:42 | fail | test_taint | request.GET.popitem()[1] |
| taint_test.py:43 | fail | test_taint | request.GET.popitem()[1][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 | fail | test_taint | request.POST |
| taint_test.py:52 | fail | test_taint | request.COOKIES |
| taint_test.py:53 | fail | test_taint | request.COOKIES["key"] |
| taint_test.py:54 | fail | test_taint | request.COOKIES.get(..) |
| taint_test.py:57 | fail | test_taint | request.FILES |
| taint_test.py:58 | fail | test_taint | request.FILES["key"] |
| 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"] |
@@ -37,7 +37,7 @@
| 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 | fail | test_taint | request.FILES.get(..) |
| 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] |
@@ -45,13 +45,13 @@
| 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 | fail | test_taint | request.META |
| taint_test.py:78 | fail | test_taint | request.META["HTTP_USER_AGENT"] |
| taint_test.py:79 | fail | test_taint | request.META.get(..) |
| taint_test.py:82 | fail | test_taint | request.headers |
| taint_test.py:83 | fail | test_taint | request.headers["user-agent"] |
| taint_test.py:84 | fail | test_taint | request.headers["USER_AGENT"] |
| taint_test.py:87 | fail | test_taint | request.resolver_match |
| 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 |
@@ -63,10 +63,10 @@
| 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 | fail | test_taint | args |
| taint_test.py:109 | fail | test_taint | args[0] |
| taint_test.py:110 | fail | test_taint | kwargs |
| taint_test.py:111 | fail | test_taint | kwargs["key"] |
| 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() |