|
| 1 | +"""testing views for Django 2.x and 3.x""" |
| 2 | +from django.urls import path, re_path |
| 3 | +from django.http import HttpResponse |
| 4 | +from django.views import View |
| 5 | + |
| 6 | + |
| 7 | +def url_match_xss(request, foo, bar, no_taint=None): |
| 8 | + return HttpResponse('url_match_xss: {} {}'.format(foo, bar)) |
| 9 | + |
| 10 | + |
| 11 | +def get_params_xss(request): |
| 12 | + return HttpResponse(request.GET.get("untrusted")) |
| 13 | + |
| 14 | + |
| 15 | +def post_params_xss(request): |
| 16 | + return HttpResponse(request.POST.get("untrusted")) |
| 17 | + |
| 18 | + |
| 19 | +def http_resp_write(request): |
| 20 | + rsp = HttpResponse() |
| 21 | + rsp.write(request.GET.get("untrusted")) |
| 22 | + return rsp |
| 23 | + |
| 24 | + |
| 25 | +class Foo(object): |
| 26 | + # Note: since Foo is used as the super type in a class view, it will be able to handle requests. |
| 27 | + |
| 28 | + # TODO: Currently we don't flag `untrusted` as a DjangoRequestParameter |
| 29 | + def post(self, request, untrusted): |
| 30 | + return HttpResponse('Foo post: {}'.format(untrusted)) |
| 31 | + |
| 32 | + |
| 33 | +class ClassView(View, Foo): |
| 34 | + # TODO: Currently we don't flag `untrusted` as a DjangoRequestParameter |
| 35 | + def get(self, request, untrusted): |
| 36 | + return HttpResponse('ClassView get: {}'.format(untrusted)) |
| 37 | + |
| 38 | + |
| 39 | +def show_articles(request, page_number=1): |
| 40 | + page_number = int(page_number) |
| 41 | + return HttpResponse('articles page: {}'.format(page_number)) |
| 42 | + |
| 43 | + |
| 44 | +def xxs_positional_arg(request, arg0, arg1, no_taint=None): |
| 45 | + return HttpResponse('xxs_positional_arg: {} {}'.format(arg0, arg1)) |
| 46 | + |
| 47 | + |
| 48 | +urlpatterns = [ |
| 49 | + re_path(r'^url_match/(?P<foo>[^/]+)/(?P<bar>[^/]+)$', url_match_xss), |
| 50 | + re_path(r'^get_params$', get_params_xss), |
| 51 | + re_path(r'^post_params$', post_params_xss), |
| 52 | + re_path(r'^http_resp_write$', http_resp_write), |
| 53 | + re_path(r'^class_view/(?P<untrusted>.+)$', ClassView.as_view()), |
| 54 | + |
| 55 | + # one pattern to support `articles/page-<n>` and ensuring that articles/ goes to page-1 |
| 56 | + re_path(r'articles/^(?:page-(?P<page_number>\d+)/)?$', show_articles), |
| 57 | + # passing as positional argument is not the recommended way of doing things, but it is certainly |
| 58 | + # possible |
| 59 | + re_path(r'^([^/]+)/(?:foo|bar)/([^/]+)$', xxs_positional_arg, name='xxs_positional_arg'), |
| 60 | +] |
| 61 | + |
| 62 | + |
| 63 | +# Show we understand the keyword arguments to from django.urls.re_path |
| 64 | + |
| 65 | +def re_path_kwargs(request): |
| 66 | + return HttpResponse('re_path_kwargs') |
| 67 | + |
| 68 | + |
| 69 | +urlpatterns = [ |
| 70 | + re_path(view=re_path_kwargs, regex=r'^specifying-as-kwargs-is-not-a-problem$') |
| 71 | +] |
| 72 | + |
| 73 | +################################################################################ |
| 74 | +# Using path |
| 75 | +################################################################################ |
| 76 | + |
| 77 | +# saying page_number is an externally controlled *string* is a bit strange, when we have an int converter :O |
| 78 | +def page_number(request, page_number=1): |
| 79 | + return HttpResponse('page_number: {}'.format(page_number)) |
| 80 | + |
| 81 | +def foo_bar_baz(request, foo, bar, baz): |
| 82 | + return HttpResponse('foo_bar_baz: {} {} {}'.format(foo, bar, baz)) |
| 83 | + |
| 84 | +def path_kwargs(request, foo, bar): |
| 85 | + return HttpResponse('path_kwargs: {} {} {}'.format(foo, bar)) |
| 86 | + |
| 87 | +def not_valid_identifier(request): |
| 88 | + return HttpResponse('<foo!>') |
| 89 | + |
| 90 | +urlpatterns = [ |
| 91 | + path('articles/', page_number), |
| 92 | + path('articles/page-<int:page_number>', page_number), |
| 93 | + path('<int:foo>/<str:bar>/<baz>', foo_bar_baz, name='foo-bar-baz'), |
| 94 | + |
| 95 | + path(view=path_kwargs, route='<foo>/<bar>'), |
| 96 | + |
| 97 | + # We should not report there is a request parameter called `not_valid!` |
| 98 | + path('not_valid/<not_valid!>', not_valid_identifier), |
| 99 | +] |
| 100 | + |
| 101 | + |
| 102 | +################################################################################ |
| 103 | + |
| 104 | + |
| 105 | +# We should abort if a decorator is used. As demonstrated below, anything might happen |
| 106 | + |
| 107 | +# def reverse_kwargs(f): |
| 108 | +# @wraps(f) |
| 109 | +# def f_(*args, **kwargs): |
| 110 | +# new_kwargs = dict() |
| 111 | +# for key, value in kwargs.items(): |
| 112 | +# new_kwargs[key[::-1]] = value |
| 113 | +# return f(*args, **new_kwargs) |
| 114 | +# return f_ |
| 115 | + |
| 116 | +# @reverse_kwargs |
| 117 | +# def decorators_can_do_anything(request, oof, foo=None): |
| 118 | +# return HttpResponse('This is a mess'[::-1]) |
| 119 | + |
| 120 | +# urlpatterns = [ |
| 121 | +# path('rev/<foo>', decorators_can_do_anything), |
| 122 | +# ] |
0 commit comments