使用 $_REQUEST[] 有什么问题?

2022-08-30 07:16:24

我在这里看到一些帖子说不要使用这个变量。我通常不会,但有时它很方便。这是怎么回事?$_REQUEST


答案 1

从两者中获取输入并以组合方式绝对没有错。事实上,这就是你几乎总是想做的:$_GET$_POST

  • 对于通常通过 GET 提交的普通幂等请求,您可能想要的数据量不适合 URL,因此它已突变为 POST 请求,而不是作为实际问题。

  • 对于具有实际效果的请求,您必须检查它是否由POST方法提交。但要做到这一点,方法是显式检查,而不是依靠空的GET。无论如何,如果方法是 ,您可能仍然希望从URL中删除一些查询参数。$_SERVER['REQUEST_METHOD']$_POSTPOST

不,问题与将 GET 和 POST 参数混为一谈无关。默认情况下,它还包括 .Cookie实际上根本不像表单提交参数:您几乎不想将它们视为同一事物。$_REQUEST$_COOKIE

如果您不小心在网站上设置了与表单参数之一同名的 Cookie,则依赖于该参数的表单将由于 Cookie 值覆盖预期参数而神秘地停止正常工作。如果您在同一站点上有多个应用程序,这很容易做到,并且当您只有几个用户使用旧cookie时,您可能很难调试,您不再使用任何cookie,并以其他人无法复制的方式破坏表单。

您可以使用 PHP 5.3 中的 request_order 配置将此行为更改为更合理(否)的顺序。如果这是不可能的,我个人会避免,如果我需要一个组合的GET+POST数组,请手动创建它。GPC$_REQUEST


答案 2

我一直在挖掘一些关于PHP Internals的新闻组帖子,并发现了关于这个主题的有趣讨论。最初的话题是关于其他事情的,但是PHP世界中(如果不是)安全专家Stefan Esser的评论将讨论转向了在一些帖子中使用_REQUEST美元的安全影响。

引用 Stefan Esser 关于 PHP Internals

$_REQUEST是PHP中最大的设计弱点之一。每个使用 _REQUEST 美元的应用程序都很可能容易受到延迟跨站点请求伪造问题的影响。(这基本上意味着,例如,如果存在名为(age)的cookie,它将始终覆盖GET / POST内容,因此将执行不需要的请求)

并在稍后回复同一线程

这不是关于有人可以伪造GET,POST的事实;饼干变量。这是关于COCHITIE将在请求中覆盖GET和POST数据的事实。

因此,我可能会用一个cookie感染您的浏览器,例如action=logout,从那天起,您就不能再使用该应用程序了,因为REQUEST[action]将永远注销(直到您手动删除cookie)。

用COOKIE感染你是如此简单...
a) 我可以在子域上的任何应用程序中使用 XSS vuln b) 当您拥有单个域
时,是否尝试过为 *.co.uk 或 *.co.kr 设置 cookie?
c) 其他跨域方式...

如果你认为这不是一个问题,那么我可以告诉你,设置一个简单的可能性,例如*.co.kr cookie,导致几个PHP版本只是返回白页。想象一下:只需一个cookie就可以杀死*.co.kr 中的所有PHP页面

通过在名为+PHPSESSID=illegal的变量中设置对*.co.kr 有效的cookie中的非法会话ID,您仍然可以使用PHP会话在韩国DOS每个PHP应用程序...

讨论继续进行,以增加一些帖子,并且阅读起来很有趣。


如您所见,_REQUEST美元的主要问题不在于它具有来自$ _GET和$ _POST的数据,而且还来自$ _COOKIE。列表中的其他一些人建议更改$_REQUEST的填充顺序,例如,首先用$_COOKIE填充它,但这可能会导致许多其他潜在问题,例如会话处理

不过,您可以从 $_REQUEST 全局中完全省略 $_COOKIES,这样它就不会被任何其他数组覆盖(实际上,您可以将其限制为其标准内容的任意组合,如 variable_order ini 设置上的 PHP 手册告诉我们:

variable_order 设置 EGPCS(环境、获取、发布、Cookie 和服务器)变量解析的顺序。例如,如果variables_order设置为“SP”,则PHP将创建超全球$_SERVER和$_POST,但不创建$_ENV,$_GET和$_COOKIE。设置为 “” 表示不会设置任何超全局。

但话又说回来,你也可以考虑不完全使用_REQUEST美元,因为在PHP中,你可以在自己的全局变量中访问环境、获取、发布、Cookie和服务器,并且少一个攻击媒介。您仍然需要清理这些数据,但这少了一件需要担心的事情。


现在您可能想知道,为什么$_REQUEST毕竟存在,为什么它没有被删除。这在PHP内部软件上也被问到。引用 Rasmus Lerdorf 关于 PHP Internals 上为什么存在 $_REQUEST?

我们删除的类似内容越多,人们就越难快速迁移到更新,更快,更安全的PHP版本。这给每个人带来的挫败感要比一些“丑陋”的遗留功能多得多。如果有一个体面的技术原因,性能或安全性,那么我们需要仔细研究一下。在这种情况下,我们应该关注的不是我们是否应该删除$_REQUEST,而是我们是否应该从中删除cookie数据。许多配置已经这样做了,包括我自己的所有配置,并且有一个强大的有效安全理由不将cookie包含在_REQUEST美元中。大多数人使用$ _REQUEST来表示GET或POST,没有意识到它也可能包含cookie,因此坏人可能会做一些cookie注入技巧并破坏幼稚的应用程序。

无论如何,希望能带来一些启示。


推荐