【问题标题】:Which $_SERVER variables are safe?哪些 $_SERVER 变量是安全的?
【发布时间】:2011-09-22 10:03:21
【问题描述】:

用户可以控制的任何变量,攻击者也可以控制,因此是攻击的来源。这被称为“污染”变量,并且是不安全的。

使用$_SERVER 时,可以控制许多变量。 PHP_SELFHTTP_USER_AGENTHTTP_X_FORWARDED_FORHTTP_ACCEPT_LANGUAGE 等许多是客户端发送的 HTTP 请求标头的一部分。

有人知道$_SERVER 变量的“安全列表”或未污染列表吗?

【问题讨论】:

  • 取决于您如何定义“安全”。这些值都是安全的,它只取决于你使用它们的目的。
  • 我认为在这种情况下,Rook 是在说“哪些服务器变量不能被用户欺骗”,比如REMOTE_ADDR
  • 任何以HTTP_ 开头的都是请求头,可以由浏览器或代理设置。我会将这些视为任何其他用户输入。
  • @bob-the-destroyer REMOTE_ADDR 是直接从 apache 的 TCP 套接字拉取的,这个值不能在 Internet 上被欺骗,因为是三次握手。
  • @Rook:好点。我想提到“欺骗”,我更倾向于 IP 欺骗本身的旧行为,而不是任何形式的伪造 REMOTE_ADDR 的实际值。这超出了这个问题的范围。很高兴了解这个值是如何设置的,谢谢。

标签: php security


【解决方案1】:

没有“安全”或“不安全”值之类的东西。只有服务器控制的值和用户控制的值,您需要了解值的来源以及是否可以出于特定目的信任它。例如,$_SERVER['HTTP_FOOBAR'] 存储在数据库中是完全安全的,但我肯定不会 eval 它。

因此,让我们将这些值分为三类:

服务器控制

这些变量由服务器环境设置,完全取决于服务器配置。

  • 'GATEWAY_INTERFACE'
  • 'SERVER_ADDR'
  • 'SERVER_SOFTWARE'
  • 'DOCUMENT_ROOT'
  • 'SERVER_ADMIN'
  • 'SERVER_SIGNATURE'

部分服务器控制

这些变量取决于客户端发送的特定请求,但只能采用有限数量的有效值,因为所有无效值都应被 Web 服务器拒绝,并且不会导致脚本调用开始。因此它们可以被认为是可靠的

  • 'HTTPS'
  • 'REQUEST_TIME'
  • 'REMOTE_ADDR' *
  • 'REMOTE_HOST' *
  • 'REMOTE_PORT' *
  • 'SERVER_PROTOCOL'
  • 'HTTP_HOST'
  • 'SERVER_NAME'
  • 'SCRIPT_FILENAME'
  • 'SERVER_PORT'
  • 'SCRIPT_NAME'

* REMOTE_ 值保证是客户端的有效地址,由 TCP/IP 握手验证。这是将发送任何响应的地址。 REMOTE_HOST 依赖于反向 DNS 查找,因此可能会被针对您的服务器的 DNS 攻击所欺骗(在这种情况下,无论如何您都会遇到更大的问题)。这个值可能是一个代理,它是 TCP/IP 协议的一个简单现实,你无能为力。

† 如果您的网络服务器响应 any 请求而不管 HOST 标头如何,这也应被视为不安全。见How safe is $_SERVER[“HTTP_HOST”]?
另见http://shiflett.org/blog/2006/mar/server-name-versus-http-host

‡ 参见https://bugs.php.net/bug.php?id=64457http://httpd.apache.org/docs/current/mod/core.html#usecanonicalphysicalporthttp://httpd.apache.org/docs/2.4/mod/core.html#comment_999

完全任意的用户控制值

这些值根本不检查,不依赖于任何服务器配置,它们完全是客户端发送的任意信息。

  • 'argv''argc'(仅适用于 CLI 调用,通常与 Web 服务器无关)
  • 'REQUEST_METHOD' §
  • 'QUERY_STRING'
  • 'HTTP_ACCEPT'
  • 'HTTP_ACCEPT_CHARSET'
  • 'HTTP_ACCEPT_ENCODING'
  • 'HTTP_ACCEPT_LANGUAGE'
  • 'HTTP_CONNECTION'
  • 'HTTP_REFERER'
  • 'HTTP_USER_AGENT'
  • 'AUTH_TYPE'
  • 'PHP_AUTH_DIGEST'
  • 'PHP_AUTH_USER'
  • 'PHP_AUTH_PW'
  • 'PATH_INFO'
  • 'ORIG_PATH_INFO'
  • 'REQUEST_URI'(可能包含污染数据)
  • 'PHP_SELF'(可能包含污染数据)
  • 'PATH_TRANSLATED'
  • 任何其他'HTTP_'

§ 只要网络服务器只允许某些请求方法,就可以被认为是可靠的

‖ 如果身份验证完全由 Web 服务器处理,则可能被认为是可靠

超全局$_SERVER 还包括几个环境变量。这些是否“安全”取决于它们的定义方式(和位置)。它们的范围可以从完全由服务器控制到完全由用户控制。

【讨论】:

  • @Rook 但正如我所说,这完全取决于您如何使用它。值本身既不安全也不不安全,这取决于您使用它们的目的。即使是恶意用户发送的数据也是完全安全的,只要您不对其进行任何可能危及您安全的事情。
  • @Rook:您对“安全”的想法让这个问题看起来有点武断,尤其是因为它完全与 PHP 的一个不起眼的扩展或自定义版本相关联。虽然您说“不应该采用“从臀部射击”的方法”,但实际上任何答案似乎都需要至少熟悉 PHP 源代码才能了解这些值是如何设置的。向 PHP 开发人员发送电子邮件不是寻找答案的更好方法吗?
  • @Rook:沟通不畅。正如 deceze 暗示的那样,“出于什么目的安全”。正如我所暗示的,您的目的是未知的,此外还有其他几个未记录的 $_SERVER 值,具体取决于文件的提供方式。在我看来,记录在案的并没有阐明真正的来源。否则我相信你不会问这个问题。很高兴你有一个可以使用的列表。但我仍然建议提交错误报告(当他们的错误站点修复时),向文档维护者发送电子邮件,或自己更新文档(如果您知道链接)。了解这些信息将使社区受益。
  • SERVER_NAME 不一定由服务器控制。根据网关和设置,它可能会从 HTTP_HOST 复制,因此受到相同的警告。
  • @deceze @Rook SERVER_PORT 需要那个小十字架吗? bugs.php.net/bug.php?id=64457
【解决方案2】:

在 PHP 中,每个以 HTTP_ 开头的 $_SERVER 变量都可以受到用户的影响。例如,变量 $_SERVER['HTTP_REINERS'] 可以通过将 HTTP 标头 REINERS 设置为 HTTP 请求中的任意值来污染。

【讨论】:

  • 重新“任意”;不是完全任意的,因为它们符合一种格式。例如,$_SERVER['HTTP_REINERS'] 在大多数 sapi 下不能包含换行符。
猜你喜欢
  • 2014-06-05
  • 1970-01-01
  • 2017-09-13
  • 2010-11-23
  • 2011-06-14
  • 1970-01-01
  • 1970-01-01
  • 2015-05-17
  • 2021-03-12
相关资源
最近更新 更多