是否需要在PHP标头中使用它之前清理$ _POST值(用于重定向)

时间:2011-11-27 14:43:45

标签: php security redirect http-headers sanitization

我是否可以安全地在PHP重定向标头中使用发布值而不检查它:

header( "Location: $base".$_POST['return'] ); // $base is set to the base of the site

(如果用户以某种方式操纵return到不存在的文件,它只会返回一条很好的404消息)

这样做有危险吗?用户是否可以将其设置为可能危及系统或以任何方式损坏系统?

3 个答案:

答案 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?

事实上,即使是精心设计的应用也不是那种防弹。退后一步,试着记住你的最后一个'啊,我忘记了什么。让我们把它解决'事件。

您是否检查了每个点控制每个和任何条件?

  • 用户点击两次网络表单提交按钮。因此控制器运行两次。
  • 用户按F5,重新提交最后一次更新控制器两次。
  • 用户以某种方式操纵参数,并在传入off值时调用控制器。

因此,我建议不要直接传递链接或其他参数,也不建议不受保护/未经验证

<强> @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

希望有帮助...