Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python: open redirect protection example is still vulnerable #16041

Closed
stsewd opened this issue Mar 25, 2024 · 4 comments · Fixed by #16646
Closed

Python: open redirect protection example is still vulnerable #16041

stsewd opened this issue Mar 25, 2024 · 4 comments · Fixed by #16646
Assignees
Labels
Python question Further information is requested

Comments

@stsewd
Copy link

stsewd commented Mar 25, 2024

The open redirect protection for this example is still vulnerable

target = request.args.get('target', '')
target = target.replace('\\', '')
if not urlparse(target).netloc:
# relative path, safe to redirect
return redirect(target, code=302)

A target like https:/example.com (notice the single /) will be parsed as having no netloc, but browsers will redirect to https://example.com (tested on Firefox and Chrome using Fedora).

from urllib.parse import urlparse

print(urlparse('https:/example.com'))
# ParseResult(scheme='https', netloc='', path='/example.com', params='', query='', fragment='')

See Django for example

https://github.com/django/django/blob/f339c4c8e4870f23d3ba8bf8ee68c57628739592/django/utils/http.py#L356-L361

@stsewd stsewd added the question Further information is requested label Mar 25, 2024
@RasmusWL
Copy link
Member

Thanks 👍 We recently changed this example, thanks for letting us know about this 💪 I'll look into rewriting our example to account for this edge-case, unless you have a suggestion for a "safe" rewrite?

(I'll also look into ensuring that our modeling recognize this edge-case)

@stsewd
Copy link
Author

stsewd commented Mar 27, 2024

unless you have a suggestion for a "safe" rewrite?

Hmm, good question. I was about to suggest to check for the protocol as well like Django does, but in the past I've solved this by just forcing the target to start with one / (check for \ as well) or by adding the hostname to it.

For A:

  • //example.com -> /example.com
  • https://example.com -> /https://example.com

For B:

  • //example.com -> https://mydomain.com//example.com
  • https://example.com -> https://mydomain.com/https://example.com

@RasmusWL
Copy link
Member

RasmusWL commented Jun 3, 2024

This one got away from me, but I've created #16646 now to address the issue 👍

@RasmusWL
Copy link
Member

RasmusWL commented Jun 4, 2024

Even though the PR is merged, it will take a little time for the documentation page to show the new text+example (since that is only updated after we make a release that contains these changes)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Python question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants