mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Python: Add taint test for django v2/v3
This commit is contained in:
@@ -24,5 +24,8 @@
|
||||
| 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= |
|
||||
| testapp/views.py:6:37:6:51 | Comment # $routeHandler | Missing result:routeHandler= |
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
| taint_test.py:7 | fail | test_taint | bar |
|
||||
| taint_test.py:7 | fail | test_taint | foo |
|
||||
| taint_test.py:8 | ok | test_taint | baz |
|
||||
| taint_test.py:14 | fail | 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: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: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: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 | fail | 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 | 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: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 | 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: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:130 | fail | test_taint | request.build_absolute_uri(..) |
|
||||
| taint_test.py:133 | ok | 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: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:149 | fail | test_taint | request.get_signed_cookie(..) |
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
"""testing views for Django 2.x and 3.x"""
|
||||
from django.urls import path
|
||||
from django.http import HttpRequest
|
||||
|
||||
|
||||
def test_taint(request: HttpRequest, foo, bar, baz=None): # $routeHandler $routedParameter=foo $routedParameter=bar
|
||||
ensure_tainted(foo, bar)
|
||||
ensure_not_tainted(baz)
|
||||
|
||||
# Manually inspected all fields of the HttpRequest object
|
||||
# https://docs.djangoproject.com/en/3.0/ref/request-response/#httprequest-objects
|
||||
|
||||
ensure_tainted(
|
||||
request,
|
||||
|
||||
request.body,
|
||||
request.path,
|
||||
request.path_info,
|
||||
|
||||
# With CSRF middleware disabled, it's possible to use custom methods,
|
||||
# for example by `curl -X FOO <url>`
|
||||
request.method,
|
||||
|
||||
request.encoding,
|
||||
request.content_type,
|
||||
|
||||
# Dict[str, str]
|
||||
request.content_params,
|
||||
request.content_params["key"],
|
||||
request.content_params.get("key"),
|
||||
|
||||
# django.http.QueryDict
|
||||
# see https://docs.djangoproject.com/en/3.0/ref/request-response/#querydict-objects
|
||||
request.GET,
|
||||
request.GET["key"],
|
||||
request.GET.get("key"),
|
||||
request.GET.getlist("key"),
|
||||
request.GET.getlist("key")[0],
|
||||
request.GET.pop("key"),
|
||||
request.GET.pop("key")[0],
|
||||
request.GET.popitem()[0], # key
|
||||
request.GET.popitem()[1], # values
|
||||
request.GET.popitem()[1][0], # values[0]
|
||||
request.GET.dict(),
|
||||
request.GET.dict()["key"],
|
||||
request.GET.urlencode(),
|
||||
|
||||
# django.http.QueryDict (same as above, did not duplicate tests)
|
||||
request.POST,
|
||||
|
||||
# Dict[str, str]
|
||||
request.COOKIES,
|
||||
request.COOKIES["key"],
|
||||
request.COOKIES.get("key"),
|
||||
|
||||
# MultiValueDict[str, UploadedFile]
|
||||
request.FILES,
|
||||
request.FILES["key"],
|
||||
request.FILES["key"].content_type,
|
||||
request.FILES["key"].content_type_extra,
|
||||
request.FILES["key"].content_type_extra["key"],
|
||||
request.FILES["key"].charset,
|
||||
request.FILES["key"].name,
|
||||
request.FILES["key"].file,
|
||||
request.FILES["key"].file.read(),
|
||||
|
||||
request.FILES.get("key"),
|
||||
request.FILES.get("key").name,
|
||||
request.FILES.getlist("key"),
|
||||
request.FILES.getlist("key")[0],
|
||||
request.FILES.getlist("key")[0].name,
|
||||
request.FILES.dict(),
|
||||
request.FILES.dict()["key"],
|
||||
request.FILES.dict()["key"].name,
|
||||
|
||||
# Dict[str, Any]
|
||||
request.META,
|
||||
request.META["HTTP_USER_AGENT"],
|
||||
request.META.get("HTTP_USER_AGENT"),
|
||||
|
||||
# HttpHeaders (case insensitive dict-like)
|
||||
request.headers,
|
||||
request.headers["user-agent"],
|
||||
request.headers["USER_AGENT"],
|
||||
|
||||
# django.urls.ResolverMatch
|
||||
request.resolver_match,
|
||||
request.resolver_match.args,
|
||||
request.resolver_match.args[0],
|
||||
request.resolver_match.kwargs,
|
||||
request.resolver_match.kwargs["key"],
|
||||
|
||||
request.get_full_path(),
|
||||
request.get_full_path_info(),
|
||||
# build_absolute_uri handled below
|
||||
# get_signed_cookie handled below
|
||||
|
||||
request.read(),
|
||||
request.readline(),
|
||||
request.readlines(),
|
||||
request.readlines()[0],
|
||||
[line for line in request],
|
||||
)
|
||||
|
||||
# django.urls.ResolverMatch also supports iterable unpacking
|
||||
_view, args, kwargs = request.resolver_match
|
||||
ensure_tainted(
|
||||
args,
|
||||
args[0],
|
||||
kwargs,
|
||||
kwargs["key"],
|
||||
)
|
||||
|
||||
ensure_not_tainted(
|
||||
request.current_app,
|
||||
|
||||
# Django has `ALLOWED_HOSTS` to ensure the HOST value cannot be tampered with.
|
||||
# It is possible to remove this protection, but it seems reasonable to assume
|
||||
# people don"t do this by default.
|
||||
request.get_host(),
|
||||
request.get_port(),
|
||||
)
|
||||
|
||||
####################################
|
||||
# build_absolute_uri
|
||||
####################################
|
||||
ensure_tainted(
|
||||
request.build_absolute_uri(),
|
||||
request.build_absolute_uri(request.GET["key"]),
|
||||
request.build_absolute_uri(location=request.GET["key"]),
|
||||
)
|
||||
ensure_not_tainted(
|
||||
request.build_absolute_uri("/hardcoded/"),
|
||||
request.build_absolute_uri("https://example.com"),
|
||||
)
|
||||
|
||||
####################################
|
||||
# get_signed_cookie
|
||||
####################################
|
||||
# We don't consider user to be able to tamper with cookies that are signed
|
||||
ensure_not_tainted(
|
||||
request.get_signed_cookie("key"),
|
||||
request.get_signed_cookie("key", salt="salt"),
|
||||
request.get_signed_cookie("key", max_age=60),
|
||||
)
|
||||
# However, providing tainted default value might result in taint
|
||||
ensure_tainted(
|
||||
request.get_signed_cookie("key", request.COOKIES["key"]),
|
||||
request.get_signed_cookie("key", default=request.COOKIES["key"]),
|
||||
)
|
||||
|
||||
|
||||
# fake setup, you can't actually run this
|
||||
urlpatterns = [
|
||||
path("test-taint/<foo>/<bar>", test_taint), # $routeSetup="test-taint/<foo>/<bar>"
|
||||
]
|
||||
Reference in New Issue
Block a user