-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Description
Deployment Type
Self-hosted
NetBox Version
v3.7.5
Python Version
3.10
Steps to Reproduce
The NetBox application makes use of redirection on several endpoints. The redirect URL is being supplied through the next_urls parameter.
The HTTP parameter next_urls gets filtered by the following snippet in order to only accept relative URL:
class GetReturnURLMixin:
"""
Provides logic for determining where a user should be redirected after processing a form.
"""
default_return_url = None
def get_return_url(self, request, obj=None):
# First, see if `return_url` was specified as a query parameter or form data. Use this URL only if it's
# considered safe.
return_url = request.GET.get('return_url') or request.POST.get('return_url')
if return_url and return_url.startswith('/'):
return return_url
# Next, check if the object being modified (if any) has an absolute URL.
if obj is not None and obj.pk and hasattr(obj, 'get_absolute_url'):
return obj.get_absolute_url()
# Fall back to the default URL (if specified) for the view.
if self.default_return_url is not None:
return reverse(self.default_return_url)
However, the filtering function is only checking that the supplied parameter next_url starts with a /.
This way, it is possible to circumvent this filtering by supplying a double-slashed payload. As an example the following payload would work : //www.google.com
POST /extras/bookmarks/6/delete/?return_url=//www.google.com HTTP/1.1
Host: REDACTED
Cookie: csrftoken=uHkNYy7ewwULISUm6oRD79cYuqcYn6GG; sessionid=REDACTED
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://REDACTED/ipam/ip-addresses/1/
csrfmiddlewaretoken=bvb14AzMDUJikxAesgo30mlhfK3T9Fk5v2lESYwQZgtTSfkqou5wXln5z05HmBQB&confirm=true
As expected, once the request is submitted, the application responds with a 302 status code which includes the new location header :
HTTP/1.1 302 Found
Server: nginx/1.20.1
Date: Tue, 28 May 2024 09:25:17 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: close
Location: //www.google.com
One could expect the redirection to fail. Indeed, according to RFC 7231, which defines HTTP/1.1 semantics and content, the Location header field's value must be a valid URI reference.
However, as the RFC does not explicitly mention schema less URLs, they are considered valid URI references. As such it is up to the browser to decide which default schema to use. For Chrome and Firefox it is defaulting to HTTP or HTTPS resulting in a valid redirection.
Expected Behavior
An HTTP error response or a redirect to the main page.
Observed Behavior
Redirect to the targeted website.