我正在使用Flask,我发现它可能是一个相当优雅的解决方案,只需在我的应用程序的每个端点放置一个session['next'] = request.url
,然后在登录/注销后重定向回用户的最后一页让我的登录/注销功能重定向到session.get('next')
。如果您启用USE_SESSION_FOR_NEXT.
我想确认这是一个安全的工作流程,但我不能确定是否有任何方法可以欺骗request.url,或者我是否应该在重定向之前验证下一个url,如此处所指定的:
有没有理由不采用这种方法?它似乎是一个很好,干净,简单的解决方案,可以保持URL的清洁,最大限度地减少字段/处理,并消除了打开重定向攻击的漏洞,如果您没有采取额外的步骤来验证下一个URL。有什么收获?
答案 0 :(得分:8)
<强> TL; DR 强>
这是一个安全的工作流程,假设您的服务器验证对所有安全资源的传入请求。
当您询问“我是否仍应在重定向之前验证下一个网址”时,答案是否定的,但您需要验证对该网址的所有请求(重定向后),以确保他们已登录。
在您的问题中,听起来您正试图在用户登录之前将网址隐藏起来。这不是必需的。
例如,假设您有两个网址:
url 1: "/login" # anyone can access this
url 2: "/secure_page" # only a logged in user can access this
假设用户未登录,并尝试导航至yoursite.com/secure_page
。每次都应将它们重定向到您的登录页面。如果他们知道secure_page
网址,则根本不会损害您的安全性。事实上,他们必须已经知道该网址,因为他们首先导航到该网页,因此他们输入了网页,点击了链接,或者保存在书签或浏览历史记录中。重要的是,当您处理secure_page
的请求时,您需要他们登录。
你问他们是否可以“欺骗”他们被重定向到的网址。当你在会话中保存它时,它们不能。但是,他们登录后可以点击他们想要的任何网址,所以如果他们“欺骗”该网址并不重要。
因为他们已经知道了网址并且他们可以在登录后点击他们想要的任何网址,因此您无需将该网址保密。这样做的唯一好处是美观清洁的网址。这就是为什么您会看到许多登录页面如下所示:
http://yoursite.com/login?next=secure_page
正在发生的事情是他们将下一个URL保存为HTTP GET参数。虽然它不那么“干净”,但它更明确,所以它有其优点和缺点。如果他们稍后再次访问登录页面,则不再发生重定向,这可能是您期望的行为。使用当前代码,一旦重定向在会话上,之后的下一次登录将遵循重定向,直到会话到期,这可能是在用户离开并且其他人使用该Web浏览器之后。
许多网站按照我上面展示的方式进行操作。 Django does it that way。在这种情况下,恶意链接可以提供“下一个”网址,并将其重定向到某个网上诱骗网站,但可以通过确保“下一个”网址不会离开您的网域来轻松阻止这种情况。
这是用于重定向/转发安全的basic cheat sheet(您正在重定向,但其他登陆此处的人可能正在考虑转发请求)。
答案 1 :(得分:1)
说实话,我想不出任何可行的方法来利用它。相反,假设您正确验证其他页面上的传入请求,并且已正确实施身份验证和访问控制,我无法想出任何实用的方法来利用此功能。话虽这么说,我对你的申请一无所知,肯定有一些比我更明亮的攻击者,所以请你带着一点点盐。
话虽这么说,我看不出为什么不应该验证网址的原因,至少要确保你重定向到同一域名的网页。性能成本微不足道,我认为任何与登录/注销流程相关的内容都需要额外的审查。当你收到cookie中没有这个字段的请求时,我也会确保你有一个可接受的默认情况。
答案 2 :(得分:0)
正如@brendan评论的那样,这个解决方案可以正常工作,使用@login_required装饰器来保护视图。
两种情况:
登录
您在/ index(非受保护的视图)&gt;&gt;成功登录@login_protected视图,在这种情况下,如果你回去,因为每个人都可以访问/ index,你真的不在乎
退出
您位于/个人资料视图(受保护的视图)&gt;&gt;成功注销到未受保护的视图,如果你回去,装饰者将不允许你进入视图
答案 3 :(得分:0)
但是有一个小问题。如果你的html中有多个框架,则有一个漏洞,称为clickjacking。您需要设置以下标题,以便浏览器处理剩余的标题。
<X-Frame-Options','DENY'>
虽然它不涉及重定向,但可以在这里使用。小心。