哪些$ _SERVER变量是安全的?

roo*_*ook 96 php security

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

使用时$_SERVER,可以控制许多变量.PHP_SELF,HTTP_USER_AGENT,HTTP_X_FORWARDED_FOR,HTTP_ACCEPT_LANGUAGE和许多其它的是由客户端发送的HTTP请求报头的一部分.

有没有人知道"安全列表"或无污染的$_SERVER变量列表?

dec*_*eze 144

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

†如果您的Web服务器响应任何请求而不管HOST标头,这也应被视为不安全.请参阅$ _SERVER ["HTTP_HOST"]的安全性如何?.
另请参阅http://shiflett.org/blog/2006/mar/server-name-versus-http-host.

‡见https://bugs.php.net/bug.php?id=64457,http://httpd.apache.org/docs/current/mod/core.html#usecanonicalphysicalport,HTTP://httpd.apache.组织/文档/ 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还包括几个环境变量.这些是否"安全"取决于它们的定义方式(以及在何处).它们的范围从完全由服务器控制到完全由用户控制.

  • @Rook但正如我所说,它绝对取决于*你如何使用它*.价值观本身既不安全也不安全,取决于*你用什么*.即使你没有做任何可能危及你安全的事情,即使是恶意用户发送的数据也是绝对安全的. (3认同)
  • `SERVER_NAME`不一定由服务器控制.根据网关和设置,它可能会从"HTTP_HOST"复制,因此需要遵循相同的警告. (3认同)
  • @Rook:你的"安全"的想法让这个问题看起来有点武断,特别是因为它完全依赖于一个模糊的扩展或PHP的自定义版本.虽然你说"不应该"从"臀部"方法开始拍摄,但任何答案实际上似乎都需要至少熟悉PHP源代码才能找出这些值是如何设置的.通过电子邮件发送PHP开发者不是更好的方法来找到答案吗? (2认同)
  • @Rook:沟通不畅.正如deceze暗示的那样,"为了什么目的而安全".正如我所暗示的,你的目的是未知的,此外还有其他几个未记录的`$ _SERVER`值取决于文件的服务方式.在我看来,有记录的没有澄清真正的来源.否则我相信你不会问这个问题.很高兴你有一个你可以使用的清单.但我仍然建议提交错误报告(当他们的错误网站被修复时),向文档维护人员发送电子邮件,或者自己更新文档(如果您对链接有所了解).了解这些信息对社区有利. (2认同)

小智 12

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