在Django中使用url_has_allowed_host_and_scheme后,什么时候需要使用iri_to_ur



在Django 3.0发行说明中,对url_has_allowed_host_and_scheme:做了如下评论

为了避免对有效范围的混淆,私有内部实用程序is_safe_url()被重命名为url_has_allowed_host_and_scheme()。URL有一个允许的主机和方案,这通常并不意味着它是"安全的"。例如,它可能仍然被错误地引用。确保在不受信任的URL的路径组件上也使用iri_to_uri()

我理解url_has_allowed_host_and_scheme的用途。以提供next查询参数的常见用例为例:http://example.com/foobar?next=http%3A%2F%2Fexample2.com%2Fhello。您可以对处理此路径的视图进行编程,以重定向到next参数提供的URL,在这种情况下:http://example2.com/hello。如果URL未经验证,则这是一个"开放重定向"漏洞。恶意行为者可以利用开放重定向将恶意URL隐藏在看起来值得信赖的URL后面。

您可以使用url_has_allowed_host_and_scheme来确保URL具有预期的主机名和方案。

我的问题是关于iri_to_uri。文档暗示您还需要使用此函数。我什么时候需要使用它?

以下是如何实现安全重定向:

from django.utils.http import url_has_allowed_host_and_scheme
from django.utils.encoding import iri_to_uri
from django.shortcuts import redirect
def example_view(request):
if url_has_allowed_host_and_scheme(request.GET['next'], None):
url = iri_to_uri(request.GET['next'])
return redirect(url)
else:
raise

iri_to_uri部分是确保最终结果URL被正确引用所必需的。例如:

  • 原始URL类似http://example.com/foobar?next=%2Fcaf%C3%A9%2F
  • request.GET['next']等于'/café/'
  • iri_to_uri(request.GET['next'])等于'/caf%C3%A9/'

HTTP请求中的第一行需要采用如下格式:

GET /caf%C3%A9/ HTTP/1.0

URL需要在那里转义,因为如果它包含空格之类的内容,就会破坏HTTP协议。

老实说,我仍然不完全确定为什么需要iri_to_uri,因为Django的实用程序(如redirect(会在URL到达HTTP请求的连线之前根据需要自动转义URL。

最新更新