$_SERVER['QUERY_STRING']是否安全,能否防止XSS攻击?

6

我需要创建一个表单,它的操作将带您返回到完全相同的页面 - 包括GET参数。我想我可以这样说:

echo '<form action="'.$_SERVER['SCRIPT_NAME'].'?'.$_SERVER['QUERY_STRING'].
     '" method="post">'

这似乎有效,测试通过了一些XSS攻击,因为QUERY_STRING的输出似乎是URL编码的。然而,PHP文档没有提到这一点,所以我不确定我能信任这种行为。

我上面的用法是否安全?如果不安全,我该怎么做?欢迎提供文档参考。

更新:切换到SCRIPT_NAME,我的脑子里混淆了哪个是好的,哪个是坏的,感谢指出错误。使用action=""可以很好地解决我的特定问题,但我仍然想知道QUERY_STRING是否被预处理过,以便安全使用,因为有其他时候你可能想要重复使用查询字符串,假设它是安全的。


永远不要假设。你永远不知道那些骗子能想出什么! - BoltClock
当然不是 :) 那是来自URI的原始值。 - RobertPitt
1
如果您想将用户提交回同一页,则甚至不需要指定哪个操作... - ajreal
为什么不把表单操作留空呢?这将向同一页面发送一个带有查询字符串的POST请求。 - Keyne Viana
你知道 PHP_SELF 本身是有漏洞的,对吧?正如上面的评论所说,最好将 action 留空。 - BoltClock
action 设为空并不意味着您可以免受假定的 XSS 攻击,但它会给您相同的行为。 - Amil Waduwawara
5个回答

9

您不应该信任 $_SERVER['QUERY_STRING'],因为它可能被用于XSS攻击。

在您的情况下,可以利用以下漏洞:

http://your.server.com/your_script.php?"><script>alert(111);</script>

请注意,上面的代码适用于IE;FireFox和Chrome在将查询字符串发送到Web服务器之前会有效地对其进行编码。
我总是会使用htmlentities(注意double_encode参数)来包装它,以防每个用户输入。
祝你好运!

谢谢,/这就是我想问的。/我们不能信任变量,因为它的内容取决于浏览器,太好了。 - dimo414
1
请注意重要信息。不是你不能“使用”数据,只是你不能“信任”它 :) - Álvaro González

1
这是另一个使用PHP的filter_input的实例。我的IDE NetBeans(无论你喜欢还是讨厌它)总是在我打开访问$_POST$_GET$_SERVER$_COOKIE的代码时发出警告,除非通过filter_input进行过滤。
这是因为上述原因 - 你说你信任外部数据,但如果用户可以输入或操纵它,则不能信任。
filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT);
filter_input(INPUT_SERVER, 'QUERY_STRING', FILTER_SANITIZE_STRING);

阅读更多这里


1

首先,您不能信任 $_SERVER['PHP_SELF'] (1) - 而应该使用 $_SERVER['SCRIPT_NAME']。

至于 $_SERVER['QUERY_STRING'],您应该像处理其他用户输入一样对待它。在将其用于输出之前进行过滤。我不建议在这种情况下使用某种通用过滤器。最好从您预期存在的特定部分重新组装查询字符串。


1
如果可以被XSS利用,首先需要知道哪种攻击方式。在这里发布的代码中,只有一个简单攻击使用了PHP_SELF。
但是,为了避免任何问题,您可以将表单操作留空。这将把表单发送到相同的页面,包括查询字符串。

0

我暂时想不到任何攻击方式,但是PHP_SELF本身是有漏洞的,而且你正在使用没有任何过滤的QUERY_STRING,这似乎很奇怪。

为什么不只是将action参数留空,让浏览器决定呢?如果你想要双重保险,可以使用Javascript在客户端正确执行此行为。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接