mirror of https://github.com/zulip/zulip.git
decorator: Only URL-decode application/x-www-form-urlencoded requests.
We previously parsed any request with method other than {GET, POST} and Content-Type other than multipart/form-data as if it were application/x-www-form-urlencoded. Check that Content-Type is application/x-www-form-urlencoded before parsing the body that way. Restrict this logic to {DELETE, PATCH, PUT} (having a body at all doesn’t make sense for {CONNECT, HEAD, OPTIONS, TRACE}). Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
1ff30bba7c
commit
c1a54f4567
|
@ -728,7 +728,7 @@ def process_as_post(view_func: ViewFuncT) -> ViewFuncT:
|
||||||
request.upload_handlers,
|
request.upload_handlers,
|
||||||
request.encoding,
|
request.encoding,
|
||||||
).parse()
|
).parse()
|
||||||
else:
|
elif request.content_type == "application/x-www-form-urlencoded":
|
||||||
request.POST = QueryDict(request.body, encoding=request.encoding)
|
request.POST = QueryDict(request.body, encoding=request.encoding)
|
||||||
|
|
||||||
return view_func(request, *args, **kwargs)
|
return view_func(request, *args, **kwargs)
|
||||||
|
|
|
@ -157,10 +157,10 @@ def rest_dispatch(request: HttpRequest, **kwargs: Any) -> HttpResponse:
|
||||||
# will generate the appropriate HTTP response.
|
# will generate the appropriate HTTP response.
|
||||||
raise MissingAuthenticationError()
|
raise MissingAuthenticationError()
|
||||||
|
|
||||||
if request.method not in ["GET", "POST"]:
|
if request.method in ["DELETE", "PATCH", "PUT"]:
|
||||||
# process_as_post needs to be the outer decorator, because
|
# process_as_post needs to be the outer decorator, because
|
||||||
# otherwise we might access and thus cache a value for
|
# otherwise we might access and thus cache a value for
|
||||||
# request.REQUEST.
|
# request.POST.
|
||||||
target_function = process_as_post(target_function)
|
target_function = process_as_post(target_function)
|
||||||
|
|
||||||
return target_function(request, **kwargs)
|
return target_function(request, **kwargs)
|
||||||
|
|
|
@ -311,6 +311,7 @@ Output:
|
||||||
We need to urlencode, since Django's function won't do it for us.
|
We need to urlencode, since Django's function won't do it for us.
|
||||||
"""
|
"""
|
||||||
encoded = urllib.parse.urlencode(info)
|
encoded = urllib.parse.urlencode(info)
|
||||||
|
kwargs["content_type"] = "application/x-www-form-urlencoded"
|
||||||
django_client = self.client # see WRAPPER_COMMENT
|
django_client = self.client # see WRAPPER_COMMENT
|
||||||
self.set_http_headers(kwargs)
|
self.set_http_headers(kwargs)
|
||||||
result = django_client.patch(url, encoded, **kwargs)
|
result = django_client.patch(url, encoded, **kwargs)
|
||||||
|
@ -356,6 +357,7 @@ Output:
|
||||||
self, url: str, info: Dict[str, Any] = {}, **kwargs: ClientArg
|
self, url: str, info: Dict[str, Any] = {}, **kwargs: ClientArg
|
||||||
) -> "TestHttpResponse":
|
) -> "TestHttpResponse":
|
||||||
encoded = urllib.parse.urlencode(info)
|
encoded = urllib.parse.urlencode(info)
|
||||||
|
kwargs["content_type"] = "application/x-www-form-urlencoded"
|
||||||
django_client = self.client # see WRAPPER_COMMENT
|
django_client = self.client # see WRAPPER_COMMENT
|
||||||
self.set_http_headers(kwargs)
|
self.set_http_headers(kwargs)
|
||||||
return django_client.put(url, encoded, **kwargs)
|
return django_client.put(url, encoded, **kwargs)
|
||||||
|
@ -373,6 +375,7 @@ Output:
|
||||||
self, url: str, info: Dict[str, Any] = {}, **kwargs: ClientArg
|
self, url: str, info: Dict[str, Any] = {}, **kwargs: ClientArg
|
||||||
) -> "TestHttpResponse":
|
) -> "TestHttpResponse":
|
||||||
encoded = urllib.parse.urlencode(info)
|
encoded = urllib.parse.urlencode(info)
|
||||||
|
kwargs["content_type"] = "application/x-www-form-urlencoded"
|
||||||
django_client = self.client # see WRAPPER_COMMENT
|
django_client = self.client # see WRAPPER_COMMENT
|
||||||
self.set_http_headers(kwargs)
|
self.set_http_headers(kwargs)
|
||||||
result = django_client.delete(url, encoded, **kwargs)
|
result = django_client.delete(url, encoded, **kwargs)
|
||||||
|
@ -383,19 +386,17 @@ Output:
|
||||||
def client_options(
|
def client_options(
|
||||||
self, url: str, info: Dict[str, Any] = {}, **kwargs: ClientArg
|
self, url: str, info: Dict[str, Any] = {}, **kwargs: ClientArg
|
||||||
) -> "TestHttpResponse":
|
) -> "TestHttpResponse":
|
||||||
encoded = urllib.parse.urlencode(info)
|
|
||||||
django_client = self.client # see WRAPPER_COMMENT
|
django_client = self.client # see WRAPPER_COMMENT
|
||||||
self.set_http_headers(kwargs)
|
self.set_http_headers(kwargs)
|
||||||
return django_client.options(url, encoded, **kwargs)
|
return django_client.options(url, info, **kwargs)
|
||||||
|
|
||||||
@instrument_url
|
@instrument_url
|
||||||
def client_head(
|
def client_head(
|
||||||
self, url: str, info: Dict[str, Any] = {}, **kwargs: ClientArg
|
self, url: str, info: Dict[str, Any] = {}, **kwargs: ClientArg
|
||||||
) -> "TestHttpResponse":
|
) -> "TestHttpResponse":
|
||||||
encoded = urllib.parse.urlencode(info)
|
|
||||||
django_client = self.client # see WRAPPER_COMMENT
|
django_client = self.client # see WRAPPER_COMMENT
|
||||||
self.set_http_headers(kwargs)
|
self.set_http_headers(kwargs)
|
||||||
return django_client.head(url, encoded, **kwargs)
|
return django_client.head(url, info, **kwargs)
|
||||||
|
|
||||||
@instrument_url
|
@instrument_url
|
||||||
def client_post(
|
def client_post(
|
||||||
|
|
|
@ -119,7 +119,10 @@ def generate_all_emails(request: HttpRequest) -> HttpResponse:
|
||||||
|
|
||||||
# Verification for new email
|
# Verification for new email
|
||||||
result = client.patch(
|
result = client.patch(
|
||||||
"/json/settings", urllib.parse.urlencode({"email": "hamlets-new@zulip.com"}), **host_kwargs
|
"/json/settings",
|
||||||
|
urllib.parse.urlencode({"email": "hamlets-new@zulip.com"}),
|
||||||
|
content_type="application/x-www-form-urlencoded",
|
||||||
|
**host_kwargs,
|
||||||
)
|
)
|
||||||
assert result.status_code == 200
|
assert result.status_code == 200
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue