首页 > 解决方案 > 如何让 is_safe_url() 函数与 Flask 一起使用,它是如何工作的?

问题描述

Flask-Login 建议在用户登录后使用 is_safe_url() 函数:

这是讨论此问题的文档部分的链接: https ://flask-login.readthedocs.io/en/latest/#login-example

他们链接到这个片段,但我不明白它是如何实现的is_safe_url()https ://palletsprojects.com/p/flask/

next = request.args.get('next')
if not is_safe_url(next):
     return abort(400)

这似乎没有随 Flask 一起提供。我对编码比较陌生。我想了解:

编辑:添加到 Flask-Login 文档的链接并包含片段。

标签: pythonsecurityflask

解决方案


正如评论中提到的,今天(2020-04-26)的 Flask-Login 在文档中存在死链接( GitHub 上的问题)。请注意原始烧瓶片段文档中的警告:

片段是非官方的且未维护的。没有 Flask 维护者策划或检查代码片段的安全性、正确性或设计。

片段是

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

现在来解决您的问题:

当 request 得到下一个参数时到底发生了什么?

我们在这里关注的部分代码是

next = request.args.get('next')
return redirect(next or url_for('dashboard')) 

默认情况下将用户重定向到仪表板(例如成功登录后)。但是,如果用户尝试访问例如端点profile并且没有登录,我们希望将他重定向到登录页面。登录后,默认重定向会将用户重定向到dashboard而不是profile他打算去的地方。为了提供更好的用户体验,我们可以通过构建 URL /login?next=profile将用户重定向到他的个人资料页面,这使烧瓶能够重定向到profile而不是默认的dashboard

由于用户可以滥用 URL,我们要检查 URL 是否安全,否则中止。

is_safe_url() 函数如何确保 URL 安全?

有问题的代码段是一个确保重定向目标将指向同一服务器的函数。

是否只需要在登录时检查下一个 URL?还是在其他地方和时间包含此安全措施很重要?

不,您应该检查所有危险的 URL。安全 URL 重定向的示例是redirect(url_for('index')),因为它在您的程序中进行了硬编码。请参阅Unvalidated Redirects and Forwards - OWASP 备忘单上的安全和危险 URL 示例。

最重要的是:是否有一个可靠的 is_safe_url() 函数可以与 Flask 一起使用?

Django 的 is_safe_url() 作为独立包捆绑在pypi上。


推荐阅读