如何获得与 Flask 一起使用的 is_safe_url() 函数以及它是如何工作的?

Pet*_*and 14 python security 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)
Run Code Online (Sandbox Code Playgroud)

这似乎不是 Flask 自带的。我对编码比较陌生。我想明白:

  • request获取next参数时究竟发生了什么?

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

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

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

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

fra*_*eze 20

正如评论中提到的,今天(2020 年 4 月 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
Run Code Online (Sandbox Code Playgroud)

现在回答您的问题:

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

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

next = request.args.get('next')
return redirect(next or url_for('dashboard')) 
Run Code Online (Sandbox Code Playgroud)

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

  • `next = request.args.get('next')`,next 不是内置的,我们从 request.args 获取它,我们可以使用它将用户发送到 URL 中指定的 `?next=`,独立于 Flask-Login (4认同)
  • 太好了。我相信我明白:所以 Flask-Login 有一个内置的“next”参数,它在使用“@login_required”重定向时引用该参数。为了安全地使用此功能,我首先需要确保下一个参数生成的 URL 使用安全 (http/https) 协议,并且不会重定向到其他站点。谢谢你!如果我错过了什么,请告诉我。 (2认同)