哪些$ _SERVER变量是安全的?


97

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

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

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


8
取决于您如何定义“安全”。这些值实际上是安全的,仅取决于您使用它们的目的。
deceze

6
我认为在这种情况下,Rook会说“用户不能欺骗哪个服务器变量”,例如REMOTE_ADDR
vcsjones

6
开头HTTP_是请求标头,可由浏览器或代理之间进行设置。我会将其视为任何其他用户输入。
datasage 2011年

3
@ bob-the-destroyer REMOTE_ADDR是直接从apache的TCP套接字中提取的,由于三向握手,因此无法通过 Internet 欺骗此值。

2
@Rook:好点。我猜想提到“欺骗”,我更倾向于ip欺骗本身的旧行为,而不是假装ip的实际价值REMOTE_ADDR。这将超出此问题的范围。很好地了解如何设置此值,所以谢谢。
bob-the-destroyer

Answers:


147

就没有这样的“安全”或“不安全”值。只有服务器控制的值和用户控制的值,您需要知道值的来源,因此是否可以出于特定目的信任该值。$_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=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还包括几个环境变量。这些是否“安全”取决于它们的定义方式(和位置)。它们的范围从完全由服务器控制到完全由用户控制。


3
@Rook但是正如我所说,这绝对取决于您的使用方式。值本身既不安全也不不安全,这取决于您将它们用作什么。只要您不采取任何可能危害您安全性的操作,即使从恶意用户发送的数据也是绝对安全的。
deceze

2
@Rook:您对“安全”的想法使这个问题显得有些武断,尤其是因为它完全与晦涩的扩展或自定义版本的PHP绑定在一起。虽然您说“不应该“从髋部射击””,但实际上,任何答案似乎都需要对PHP源代码有最低程度的了解,以了解如何设置这些值。给PHP开发人员发送电子邮件会不是找到答案的更好方法吗?
bob-the-destroyer

2
@Rook:沟通不畅。正如deceze暗示的那样,“出于什么目的是安全的”。正如我所暗示的,您的目的是未知的,此外,还有其他一些未记录的$_SERVER值,具体取决于文件的提供方式。我认为,有记录的文献并没有阐明真正的来源。否则,我相信您不会问这个问题。很高兴您有可以使用的清单。但是我仍然建议您提交错误报告(在错误网站已修复的情况下),向文档维护者发送电子邮件或自行更新文档(如果您不知道链接)。知道此信息将使社区受益。
bob-the-destroyer

3
SERVER_NAME不一定由服务器控制。根据网关和设置,它可能会从HTTP_HOST相同的警告中复制并因此受到同样的警告。
bobince 2012年

1
@deceze @Rook SERVER_PORT需要那个小十字架吗?bugs.php.net/bug.php?id=64457
德扬诺维奇

12

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


重新“任意”;由于它们符合格式,因此并非完全是任意的。例如,$_SERVER['HTTP_REINERS'] 在大多数sapi下不能包含换行符。
Pacerier
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.