提问人:sprugman 提问时间:1/27/2010 最后编辑:Bradsprugman 更新时间:10/28/2020 访问量:60986
使用 $_REQUEST[] 有什么问题?
What's wrong with using $_REQUEST[]?
答:
这是模糊的。您真的不知道数据是如何到达您的,因为它带有 post、get 和 cookie 数据。我不一定认为这总是一件坏事,除非你需要知道或限制交付方式。
$_REQUEST
指各种请求(GET、POST 等)。这有时很有用,但通常最好指定确切的方法(_GET 美元、_POST 美元等)。
评论
GET 请求应该是幂等的,而 POST 请求通常不是。这意味着 和 中的数据通常应以不同的方式使用。$_GET
$_POST
如果应用程序使用 中的数据,则 GET 和 POST 请求的行为相同,这违反了 GET 的幂等性。$_REQUEST
评论
唯一一次使用不是一个坏主意是使用 GET。$_REQUEST
- 如果使用它来加载 POST 值,则存在跨站点请求伪造的风险
- 如果您使用它来加载 cookie 值,则您再次面临跨站点请求伪造的风险
即使使用 GET,键入时间也比$_GET
$_REQUEST
;)
评论
$_POST
$_REQUEST
我真的很喜欢使用它。它使您可以灵活地使用 GET 或 POST,这对于大多数时候数据都是 POST 的搜索表单之类的事情会派上用场,但有时您会想说链接到特定搜索,因此您可以改用 GET 参数。
此外,如果您查看许多其他语言(例如 ASP.NET),它们根本没有区分 GET 和 POST 变量。
预计到达时间:
我从未使用 REQUEST 来获取 COOKIE 值,但我认为 Kyle Butt 在这篇文章的评论中提出了一个很好的观点。使用 REQUEST 获取 COOKIE 值不是一个好主意。我相信他是对的,如果你这样做,跨站点请求伪造确实存在一些可能性。
此外,内容加载到 REQUEST 中的顺序由 php.ini 中的配置参数(variables_order 和 request_order)控制。因此,如果您通过 POST 和 GET 传入相同的变量,那么实际进入 REQUEST 的变量取决于这些 ini 设置。如果您依赖于特定订单,并且这些设置的配置与预期不同,这可能会影响可移植性。
评论
这是非常不安全的。此外,这很尴尬,因为您不知道是收到 POST 还是 GET,还是其他请求。在设计应用程序时,您确实应该知道它们之间的区别。GET 非常不安全,因为它是在 URL 中传递的,除了页面导航之外,几乎不适合任何内容。POST 虽然本身也不安全,但提供了一级安全。
评论
了解何时使用 POST、何时使用 GET 以及何时使用 cookie 非常重要。有了 _REQUEST 美元,你所看到的价值可能来自其中任何一个。如果您希望从 POST 或 GET 或 COOKIE 中获取值,那么对于阅读您的代码的人来说,使用特定变量而不是 $_REQUEST 会提供更多信息。
其他人还指出,您不希望所有 POST 或 cookie 都被 GET 覆盖,因为所有这些 POST 或 cookie 都有不同的跨站点规则,例如,如果您在使用 $_REQUEST 时返回 ajax 数据,则容易受到跨站点脚本攻击。
可能只在您想检索当前 url 或主机名时才使用,但对于实际解析该 URL 中的数据,例如使用 & 符号的 parmeters,这可能不是一个好主意。一般来说,你不想对你正在尝试做的事情使用模糊的描述。如果你需要具体,那就是 _REQUEST 美元不好的地方,如果你不需要具体,那么请随意使用它。我会想。
评论
$_REQUEST
$_SERVER['QUERY_STRING']
从两者中获取输入并以组合方式输入绝对没有错。事实上,这就是你几乎总是想做的事情:$_GET
$_POST
对于通常通过 GET 提交的普通幂等请求,您想要的数据量可能不适合 URL,因此它实际上已更改为 POST 请求。
对于具有实际效果的请求,您必须检查它是否由 POST 方法提交。但这样做的方法是显式检查,而不是依赖于 GET 的空。无论如何,如果方法是 ,您可能仍然希望从 URL 中删除一些查询参数。
$_SERVER['REQUEST_METHOD']
$_POST
POST
不,问题与混淆 GET 和 POST 参数无关。默认情况下,它还包括 .而且 cookie 根本不像表单提交参数:您几乎不想将它们视为同一事物。$_REQUEST
$_COOKIE
如果您不小心在您的网站上设置了一个与您的表单参数同名的 cookie,那么依赖于该参数的表单将神秘地停止正常工作,因为 cookie 值覆盖了预期的参数。如果您在同一站点上有多个应用程序,这很容易做到,并且当您只有几个用户使用旧 cookie 时,您可能很难调试,您不再使用,以其他人无法复制的方式闲逛并破坏表单。
您可以在 PHP 5.3 中使用 request_order 配置将此行为更改为更合理的 (no) 顺序。如果这是不可能的,我个人会避免,如果我需要一个组合的 GET+POST 数组,请手动创建它。GP
C
$_REQUEST
评论
a="foo"
a="bar"
$_REQUEST
通常被认为是有害的,原因与简单到中等复杂度的数据转换通常在应用程序代码中执行而不是在 SQL 中声明的原因相同:一些程序员很糟糕。
因此,如果一个人倾向于在任何地方使用,我可以通过 GET 做任何事情,我可以通过 POST 做任何事情,这意味着在我的(恶意)网站上设置标签,导致登录您的电子商务模块的用户静默购买产品,或者我可以使他们点击链接,这将导致危险行为或敏感信息泄露(可能对我来说)。$_REQUEST
<img>
然而,这是因为一个新手,或者至少是没有经验的PHP程序员犯了简单的错误。首先,知道什么类型的数据是合适的。例如,我有一个 Web 服务,可以返回 URLEncoding、XML 或 JSON 的响应。应用程序通过检查 HTTP_ACCEPT 标头来决定如何格式化响应,但可以通过发送参数来强制执行响应。format
在检查 format 参数的内容时,它可以通过 querystring 或 postdata 发送,具体取决于多种因素,其中最重要的是调用应用程序是否希望将“&format=json”混合到其请求中。在这种情况下,非常方便,因为它使我不必输入如下内容:$_REQUEST
$format = isset($_POST['format']) ? $_POST['format']
: (isset($_GET['format']) ? $_GET['format'] : null);
我不打算再多说了,但我只想说,使用不会被劝阻,因为它本质上是危险的——它只是另一个工具,它完全按照要求去做,无论你是否理解这些含义——这是一个可怜的、懒惰的或没有经验的程序员的糟糕、懒惰或不知情的决定导致了这个问题。$_REQUEST
###How 安全使用###$_REQUEST
- 了解您的数据:您应该对您将获得什么样的数据有一定的期望,因此请相应地对其进行清理。数据库的数据? 或。要将其显示给用户吗? 或。期待数值数据? 或。事实上,
filter_input()
及其相关函数旨在除了检查和清理数据之外什么都不做。始终使用这些工具。addslashes()
*_escape_string()
htmlentities()
htmlspecialchars()
is_numeric()
ctype_digit()
- 不要直接访问用户提供的超全局数据。养成每次清理数据的习惯,并将数据移动到干净的变量中,即使它只是 .或者,您可以直接在超全局变量中进行清理,但我提倡使用单独变量的原因是,这样做可以很容易地发现代码中的漏洞,因为任何直接指向超全局而不是其经过审查的等价物都被认为是危险的错误。
$post_clean
- 了解数据的来源。参考上面的示例,允许通过 GET 或 POST 发送响应格式变量是完全合理的。我还允许通过任一方法发送“action”变量。但是,操作本身对可接受的 HTTP 谓词有非常具体的要求。例如,对服务使用的数据进行更改的函数只能通过 POST 发送。 对某些类型的非特权或低特权数据(例如动态生成的地图图像)的请求可以响应来自任一方法的请求。
总之,请记住这个简单的规则: ##SECURITY 就是你所做的,人们!##
###EDIT:###
我强烈推荐 bobince 的建议:如果可以,将 php.ini 中的参数设置为“GP”;也就是说,没有 cookie 组件。在 98%+ 的情况下,几乎没有合理的理由,因为 cookie 数据几乎不应该被视为与查询字符串或后数据相当。request_order
附言,轶事!
我认识一个程序员,他想到了一个地方来简单地存储数据,这些数据可以以超全局的方式访问。重要的用户名和密码,文件的路径,你的名字,它被存储在.当我告诉他这个变量的行为方式时,他有点惊讶(虽然不是很滑稽,但不幸的是)。毋庸置疑,这种做法已被废黜。$_REQUEST
$_REQUEST
我一直在挖掘一些关于PHP Internals的新闻组帖子,并发现了一个关于这个话题的有趣讨论。最初的帖子是关于其他事情的,但 Stefan Esser 的一句话,PHP 世界的安全专家(如果不是的话)将讨论转向了在一些帖子中使用 _REQUEST 美元的安全隐患。
$_REQUEST 是 PHP 中最大的设计弱点之一。每个应用程序都使用 _REQUEST 美元很可能容易受到延迟跨站点请求的影响 伪造问题。(这基本上意味着,例如,如果一个名为(年龄)的cookie) 存在,它将始终覆盖 GET/POST 内容,因此 将执行不需要的请求)
并在稍后对同一线程的回复中
这与某人可以伪造 GET、POST 的事实无关;COOKIE 变量。 这是关于 COOKIE 将覆盖 GET 和 POST 数据的事实 请求。
因此,我可以用一个cookie感染你的浏览器,例如 action=logout,从那天起您将无法使用该应用程序 因为 REQUEST[action] 将永远注销(直到您 手动删除 Cookie)。
用COOKIE感染你就是这么简单......
a) 我可以在子域
上的任何应用程序中使用 XSS 漏洞 b) 当您拥有 *.co.uk 或 *.co.kr 时,曾经尝试过为 *. 或 *. 设置 cookie 那里有单个域名?
c) 其他跨域,无论以何种方式...如果你认为这不是问题,那么我可以告诉你 有一个简单的可能性来设置 f.e. 一个 *.co.kr cookie 在几个PHP版本中,只返回白页。 想象一下:只需一个 cookie 即可杀死 *.co.kr 中的所有 PHP 页面
并通过在 cookie 中设置对 *.co.kr 有效的非法会话 ID 变量称为 +PHPSESSID=illegal,您仍然可以 DOS 每个 PHP 在韩国使用PHP会话的应用程序...
讨论继续进行,再发几篇帖子,读起来很有趣。
正如你所看到的,$_REQUEST 的主要问题不在于它有 $_GET 和 $_POST 的数据,而在于它有 $_COOKIE 的数据。列表中的其他一些人建议更改 $_REQUEST 的填充顺序,例如先用 $_COOKIE 填充它,但这可能会导致许多其他潜在问题,例如会话处理。
不过,你可以从 $_REQUEST 全局中完全省略 $_COOKIES,这样它就不会被任何其他数组覆盖(事实上,你可以将它限制为标准内容的任意组合,就像 variable_order ini 设置上的 PHP 手册告诉我们的那样:
variable_order 设置 EGPCS(Environment、Get、Post、Cookie 和 Server)变量解析的顺序。例如,如果 variables_order 设置为 “SP”,则 PHP 将创建超全局变量 $_SERVER 和 $_POST,但不会创建 $_ENV、$_GET 和 $_COOKIE。设置为 “” 表示不会设置超全局变量。
但话又说回来,你也可以考虑完全不使用 $_REQUEST,因为在 PHP 中,你可以在它们自己的全局环境中访问 Environment、Get、Post、Cookie 和 Server,并且少了一个攻击媒介。您仍然需要清理这些数据,但无需担心。
现在你可能想知道,为什么 $_REQUEST 毕竟存在,为什么它没有被删除。在 PHP Internals 上也提出了这个问题。引用 Rasmus Lerdorf 关于为什么 $_REQUEST 存在? 在 PHP 内部
我们删除的类似内容越多,人们就越难删除 快速迁移到更新、更快、更安全的 PHP 版本。那 给每个人带来的挫败感比一些“丑陋”的遗产要多得多 特征。如果有不错的技术原因,性能或 安全性,那么我们需要认真研究它。在本例中, 我们应该考虑的不是我们是否应该删除 $_REQUEST 但是我们是否应该从中删除 cookie 数据。多种配置 已经做到了,包括我自己的所有,并且有一个很强的有效性 在 _REQUEST 美元中不包含 cookie 的安全原因。大多数人使用 $_REQUEST 表示 GET 或 POST,没有意识到它也可能包含 饼干,因此坏人可能会做一些饼干注入 技巧并打破幼稚的应用程序。
无论如何,希望这能带来一些启示。
评论
如果你知道你想要什么数据,你应该明确要求它。IMO、GET 和 POST 是两种不同的动物,我想不出需要混合 POST 数据和查询字符串的充分理由。如果有人有,我会很感兴趣。
当您的脚本可能以相同的方式响应 GET 或 POST 时,使用 $_REQUEST 会很方便。我认为这应该是一个极其罕见的情况,在大多数情况下,最好使用两个单独的函数来处理两个不同的概念,或者至少检查方法并选择正确的变量。当不需要交叉引用变量可能来自哪里时,程序流通常更容易遵循。善待必须在 6 个月内维护您的代码的人。可能是你。
除了 REQUEST 变量中的 cookie 和环境变量引起的安全问题和 WTF 之外(不要让我开始使用 GLOBAL),请考虑如果 PHP 开始原生支持其他方法(如 PUT 和 DELETE)将来会发生什么。虽然这些极不可能合并到 REQUEST 超全局中,但它们有可能作为选项包含在variable_order设置中。因此,您真的不知道 REQUEST 包含什么,以及什么是优先的,尤其是当您的代码部署在第三方服务器上时。
POST 比 GET 更安全吗?没有。最好在可行的情况下使用 GET,因为在日志中更容易看到应用程序在受到攻击时是如何被利用的。POST 更适合影响域状态的操作,因为蜘蛛通常不会跟踪它们,并且预测性提取机制不会在您登录 CMS 时删除您的所有内容。然而,问题不在于 GET 与 POST 的优点,而在于接收方应该如何处理传入的数据以及为什么合并它是不好的,所以这实际上只是一个顺便说一句。
我认为没有问题,但是我们在使用它时必须小心,因为它是来自 3 个来源 (GPC) 的变量的集合。$_REQUEST
我想仍然可以使旧程序与新的 php 版本兼容,但是如果我们开始新项目(包括新库),我认为我们不应该再使用使程序更清晰。我们甚至应该考虑删除 的用法并将其替换为包装函数,以使程序更轻巧,尤其是在处理大量提交的文本数据时,因为包含 .$_REQUEST
$_REQUEST
$_REQUEST
$_REQUEST
$_POST
// delete $_REQUEST when program execute, the program would be lighter
// when large text submitted
unset($_REQUEST);
// wrapper function to get request var
function GetRequest($key, $default = null, $source = '')
{
if ($source == 'get') {
if (isset($_GET[$key])) {
return $_GET[$key];
} else {
return $default;
}
} else if ($source == 'post') {
if (isset($_POST[$key])) {
return $_POST[$key];
} else {
return $default;
}
} else if ($source == 'cookie') {
if (isset($_COOKIE[$key])) {
return $_COOKIE[$key];
} else {
return $default;
}
} else {
// no source specified, then find in GPC
if (isset($_GET[$key])) {
return $_GET[$key];
} else if (isset($_POST[$key])) {
return $_POST[$key];
} else if (isset($_COOKIE[$key])) {
return $_COOKIE[$key];
} else {
return $default;
}
}
}
达伦·库克:“从 php 5.3 开始,默认的 php.ini 说只有 GET 和 POST 数据被放入 .看看 php.net/request_order 我只是 在期待 cookie 时偶然发现了这个向后兼容性中断 数据,想知道为什么它不起作用!
$_REQUEST
$_REQUEST
哇。。。由于升级到 PHP 5.3,我的一些脚本停止工作。做了同样的事情:假设在使用变量时会设置 cookie。
随着升级,它停止了工作。$_REQUEST
我现在使用...$_COOKIE["Cookie_name"]
正如其他人所说,核心问题是它包含 cookie。
在 PHP 7 中,您可以这样做:
$request = array_merge($_GET ?? [], $_POST ?? []);
这避免了 cookie 问题,最坏的情况是给你一个空数组,充其量是 $_GET 和 $_POST 的合并,后者优先。如果您不太在意允许通过查询字符串注入参数的 URL,那就非常方便了。
只需确保在您的 php.ini 中设置正确的参数(下面是默认参数,只要不设置为 GPC,这里不使用 Cookie)
request_order = "GP"
这意味着 POST 会覆盖 GET,你会没事的。
原因只是 _GET 美元和 _POST 美元的合并。
在发送表单并通过页面上的大量链接进行导航时,有一个保存状态的位置非常有用:$_REQUEST
$_REQUEST
上一个:获取当前正在执行的方法的名称
下一个:Java 是否支持缺省参数值?
评论
$_REQUEST
$_REQUEST
request_order
PHP_INI_PERDIR