PHP的$_REQUEST方法存在安全问题吗?

17

我所阅读的教材称$_REQUEST存在安全问题,因此最好使用$_POST。

这样做可以吗?

7个回答

33

我认为将$_POST描述为比$_REQUEST更安全是有风险的。

如果数据在使用之前没有进行验证和清洗,那么就存在可能的攻击途径。

简而言之:如果数据没有得到安全地处理,那么数据来自何处都无所谓。


3
我希望我能点赞更多——从客户端获取的数据永远不能被信任——我可以像伪造其他内容一样容易地伪造POST数据。它不容易在地址栏中看到这个事实只意味着我必须使用网络数据包嗅探器来发现。始终验证传入数据,并假定来自客户端的任何数据都可能是出于恶意发送的。 - Eclipse
10
尽管你所说的是正确的,但我仍然主张从应该获取数据的地方获取数据,而不是跳过验证,而是为了简化验证。 - Vinko Vrsalovic
使用$_POST而不是$_REQUEST是否可以说更安全?使用$_POST是否有效地消除了通过URL输入数据的能力? - Nick Bedford

19

$_REQUEST有问题的原因是它会获取来自于$_GET、$_POST和$_COOKIE的值,这意味着如果你编写代码时采用了某些错误的信任客户端的假设,那么恶意用户可能会利用这一点,在不同的地方提供一个值来覆盖你尝试传递的值。

这也意味着你可能会给你的助手错误的指令,因为他可能从$_REQUEST中获取了GET或COOKIE的值。你需要使用实际出现所需值的位置,而不仅仅是$_POST


8
话虽如此,这些值中的任何一个都有可能被编辑。有许多插件可以让你在Firefox(我想其他浏览器也是)上动态更改POST数据。在几乎任何浏览器上,更改GET和COOKIE数据都很容易。 - Matthew Scharley
1
这引出了一个问题。如果某个东西应该是“安全”的,那么它不应该能够接受来自任何参数,并根据实际数据接受或拒绝吗?如果它是重复输入,因为他们刷新了它,难道你不应该看到它是重复的吗?我的意思是,这只是数据而已。无论您如何输入,都不应该有影响。是/否? - Tyler Carter
1
@matthew 你可以在其他特别设计的页面上发布表单,使用自己的数据集。 - Tyler Carter
4
@Chacha102:就理想而言,我同意你的观点。但是教授PHP用户使用$_GET和$_POST比教他们不信任客户端(甚至不知道客户端和服务器上正在发生什么),验证数据和操作以及编写安全代码要容易得多。 - chaos
@chaos:这就是问题所在。我们试图列出安全应用的规则清单,唯一可行的方法是知道你在做什么,而不是遵循规则书。 - Joeri Sebrechts
是的,没错,这就是问题所在。但由于我们无法阻止那些不知道自己在做什么的人使用PHP编写Web应用程序,因此我们必须尽力而为。参见http://en.wikipedia.org/wiki/Harm_reduction。 - chaos

8
正如几个答案中已经提到的那样:任何来自客户端的数据都不能信任,并且默认情况下必须被视为是恶意的。这包括$_POST$_GET$_COOKIE$_REQUEST(前者的组合),以及其他一些内容。
当谈到其中某些比其他更危险时,我确实会将$_GET$_REQUEST(因为它包括$_GET)与$_POST分开,因为生成(即操纵)POST请求要稍微困难一些。重点在于这里的稍微,但至少使用POST进行敏感操作可以消除另一个易受攻击的层。
特别是当涉及到跨站脚本(或XSS)和cookie盗窃时,通过简单地插入具有操纵URL的隐藏图像或伪造链接,很容易让受害者的浏览器向受攻击的服务器发出GET请求。
发出POST请求至少需要一些JavaScript,这在某些情况下稍微难以注入到受害者的浏览器中执行。显然,攻击者可以直接生成POST请求,因此也不能信任它们,但对于攻击者通过第三方浏览器进行攻击的情况,它们会更难操作。
安全始终是让应用程序尽可能难以被破解的问题 - 考虑实现约束等因素。它永远不可能是100%安全的。因此,在选择不同的实现方法时,最好选择更难以利用的替代方案,即使差异很小,这是最佳实践。
最终,总是要消除易受攻击的目标。当有升高风险的操作时,确保使用POST请求并限制自己在代码中使用“$_POST”。这样,您已经排除了一些非常容易受到GET驱动攻击的攻击方式,并且现在可以专注于验证POST数据。只是不要认为使用POST就可以默认操作是安全的。

$_REQUEST 是 $_GET、$_POST 和 $_COOKIE 的组合。而 $_COOKIE 不是复数形式。 - Josh

4

当涉及到数据获取时,告诉用户使用$_POST而不是$_REQUEST是完全可以的。更加确定数据来源始终是更好的选择。


盲目建议使用 $_POST 是一个不好的主意 -- $_REQUEST 包含了 cookies 和查询参数,开发者可能希望数据来自这些来源。更好的答案是:“如果你知道数据应该来自哪里,告诉人们使用 $_POST、$_GET 或 $_COOKIE 都可以。” - Josh

2

@Christian:

当谈到某些变量比其他变量更危险时,我会将$_GET和包含$_GET的$_REQUEST与$_POST分开,因为生成一个POST请求要稍微困难一些,即操作一个POST请求比GET请求要稍微困难。这里的重点是稍微,但至少使用POST来处理敏感操作可以减少另一个易受攻击的层面。

嘟嘟声。抱歉,但这不是真的。

任何了解GET和POST之间差异或未经过滤的输入可能被利用的人,都不会犹豫一秒钟就启动Tamper Data。

有些人在这里是正确的:在设计良好的系统中使用$_REQUEST既不会增加安全性,也不会降低安全性。


1

使用$_POST$_REQUEST之间没有真正的安全差异,您应该以同样的严谨程度对数据进行消毒。

$_REQUEST最大的问题是,您可能正在尝试从POST表单中获取数据,但可能具有相同名称的GET参数。数据将来自哪里?最好明确要求从您期望的位置请求数据,在该示例中使用$_POST

有一些微小的安全优势-在GET参数上执行XSS(更具体地说是XSRF)攻击更容易,如果您使用$_REQUEST,而您实际上只想要POST数据。

很少有情况需要从POST、GET或cookie中获取数据。如果要获取POST数据,请使用$_POST,如果要从GET参数中获取数据,请使用$_GET,如果要使用cookie数据,请使用$_COOKIE


0

最安全的方式是验证和验证数据。我通常为表单生成一个随机唯一ID并将其存储在用户的会话中,但这很容易被决心的攻击者绕过。更好的方法是清理所有传入的数据。请查看htmlspecialchars()及其相关函数。我还使用第三方工具进行跨站点脚本攻击防护,例如HTML Purifier

在一些实用的注意事项上,始终对应该是数字的内容使用intval(),转义所有传入的字符串,在电话号码、电子邮件或任何将成为SQL查询一部分的内容中使用正则表达式。

希望这对你有所帮助。


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