Issue
Flask-Login recommends having an is_safe_url() function after user login:
Here is a link to the part of the documentation that discusses this: https://flask-login.readthedocs.io/en/latest/#login-example
They link to this snippet but I don't understand how it implements is_safe_url()
:
https://palletsprojects.com/p/flask/
next = request.args.get('next')
if not is_safe_url(next):
return abort(400)
This doesn't seem to come with Flask. I'm relatively new to coding. I want to understand:
What exactly is happening when
request
gets thenext
argument?What does the
is_safe_url()
function do to ensure the URL is safe?Does the next URL need to be checked on login only? Or are there other places and times when it is important to include this security measure?
And most importantly: is there a reliable
is_safe_url()
function that I can use with Flask?
Edit: Added link to Flask-Login documentation and included snippet.
Solution
As mentioned in the comments, Flask-Login today had a dead link in the documentation (issue on GitHub). Please note the warning in the original flask snippets documentation:
Snippets are unofficial and unmaintained. No Flask maintainer has curated or checked the snippets for security, correctness, or design.
The snippet is
from urllib.parse import urlparse, urljoin
def is_safe_url(target):
ref_url = urlparse(request.host_url)
test_url = urlparse(urljoin(request.host_url, target))
return test_url.scheme in ('http', 'https') and \
ref_url.netloc == test_url.netloc
Now to address your questions:
What exactly is happening when request gets the next argument?
Part of the code we are focusing on here is
next = request.args.get('next')
return redirect(next or url_for('dashboard'))
which redirects user to dashboard (e.g. after successful login) by default. However, if user tried to reach for e.g. endpoint profile
and wasn't logged in we would want to redirect him to the login page. After logging in default redirect would redirect user to dashboard
and not to profile
where he intended to go. To provide better user experience we can redirect user to his profile page by building URL /login?next=profile
, which enables flask to redirect to profile
instead of the default dashboard
.
Since user can abuse URLs we want to check if URL is safe, or abort otherwise.
What does the is_safe_url() function do to ensure the URL is safe?
The snippet in question is a function that ensures that a redirect target will lead to the same server.
Does the next URL need to be checked on login only? Or are there other places and times when it is important to include this security measure?
No, you should check all dangerous URLs. Example of safe URL redirect would be redirect(url_for('index'))
, since its hardcoded in your program. See examples of safe and dangerous URLs on Unvalidated Redirects and Forwards - OWASP cheatsheet.
And most importantly: is there a reliable is_safe_url() function that I can use with Flask?
There is Django's is_safe_url() bundled as a standalone package on pypi.
Answered By - frainfreeze
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.