哪些$ _SERVER变量是安全的?

时间:2011-06-24 23:38:55

标签: php security

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

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

有没有人知道“安全列表”或未列出的$_SERVER变量列表?

2 个答案:

答案 0 :(得分:141)

没有“安全”或“不安全”这样的东西。只有服务器控制的值和用户控制的值,您需要知道值的来源,以及它是否可以为特定目的而信任。例如,$_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协议的简单现实,你无能为力。

†如果您的网络服务器响应任何请求而不管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服务器只允许某些请求方法,就可以认为可靠

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

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

答案 1 :(得分:11)

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