我是否可以安全地在PHP重定向标头中使用发布值而不检查它:
header( "Location: $base".$_POST['return'] ); // $base is set to the base of the site
(如果用户以某种方式操纵return
到不存在的文件,它只会返回一条很好的404消息)
这样做有危险吗?用户是否可以将其设置为可能危及系统或以任何方式损坏系统?
答案 0 :(得分:3)
header()函数不再容易受HTTP Response Splitting攻击。您唯一需要担心的漏洞是OWASP a10 - unvalidated redirects and forwards。
提供空字符串以外的任何$base
将阻止攻击者将用户转发到远程域,这对于网络钓鱼非常有用。如果将引用者作为CSRF预防的一种形式进行检查,则重定向到同一域可能对攻击者有用,但这是一种弱的保护形式,无论如何你都不应该使用它。即使有了基础,攻击者也可以通过提供类似/../../../admin.php
的值来更改路径,但这仍然相对于在大多数情况下是安全的原始域。
处理未经验证的重定向的一个好方法是完全避免使用REQUEST变量来解决问题。而是将其存储在$_SESSION['redirect']
中,并将其用于下一个请求。为了更健壮,您可以说$_SESSION['redirect_checkout']
或特定页面。
另一种选择是使用白名单,创建您想接受的所有值的列表,并确保用户提供的值在您的列表中。
答案 1 :(得分:2)
是的,绝对!不要随时信任任何$ _GET或$ _POST值!
假设第三方网站发布了表单。它可以发布任何地址。
一个简单的解决方案是不包含地址,而是将 md5()地址哈希包含在表单中。表单发布后,脚本的任务是将哈希映射到实际地址,然后发出Location
标题。
我的other post可能会引起您的兴趣。
你可能会说,你的应用程序是防弹的。为什么我不能直接传递URL?
事实上,即使是精心设计的应用也不是那种防弹。退后一步,试着记住你的最后一个'啊,我忘记了什么。让我们把它解决'事件。
您是否检查了每个点控制每个和任何条件?
因此,我建议不要直接传递链接或其他参数,也不建议不受保护/未经验证。
<强> @col。弹片:我完全清楚,任何点上的任何网址都可以提交给网络应用。那是微不足道的。
然而,在给定的控制流程点,有一些可接受的下一个控制流状态。
为了确保只有那些下一个控制流状态到达,我建议验证。
更通用的方法
事实上,我最近更新的internal framework 从未将任何参数作为GET或POST参数从请求传递到。所有参数都是从用户会话中保存和检索的[在所谓的Flow内部,是更大控制流程的一部分]。
使用该框架,只传递一个参数--FlowID。如果框架在会话的流存储中找不到FlowID,则框架会抛出异常,并且调度程序会发出错误消息。
答案 2 :(得分:-2)
我赞成了斯特凡的回答。
我也有这个补充。我写了一个很好的类来构建和解析URL。如果您愿意,可以使用它进行验证。
请参阅Url.php和UrlTest.php以了解用法。
https://github.com/homer6/altumo/tree/master/source/php/String
希望有帮助...