【问题标题】:Reliability of PHP'S $_SERVER['REMOTE_ADDR']PHP 的 $_SERVER['REMOTE_ADDR'] 的可靠性
【发布时间】:2011-10-06 14:36:05
【问题描述】:

我正在构建一个旨在从 localhost 进行管理的站点,但包含向 Internet 或本地网络用户公开数据的页面。我可以依靠 PHP 的 $_SERVER['REMOTE_ADDR'] 作为将用户识别为 localhost 的安全/可靠方式吗? 谢谢!

编辑: 澄清一下,我只关心确定请求是否来自本地主机(也许有更好的方法)。

【问题讨论】:

  • 这是相当可靠的,是的。无需澄清,我们理解;)

标签: php security


【解决方案1】:

该变量由 Apache(或其他 Web 服务器守护程序)提供的数据填充,并且在识别连接另一端的 IP 地址时应该是可靠的,是的。检查 127.x.x.x(几乎总是 127.0.0.1)和 ::1(对于 IPv6)。正如 Senica 所说,它可能并不总是存在(例如,从命令行而不是通过 Web 服务器运行时)。但是如果填满了,应该是靠谱的。

为了能够伪造它,某人已经需要对您的网络和系统进行相当广泛的访问,而您无论如何都无法使用 PHP 来防范。

【讨论】:

  • 感谢您的回复。该站点旨在部署给客户,以便在他们自己的服务器上使用。我担心这种方法可能会导致客户在服务器配置中遇到不一致的行为(因为我不能保证甚至会返回任何东西)
  • 那么您应该按照上面的定义进行检查。如果未设置 REMOTE_ADDR,则它不会作为 HTTP 请求传入。这种可能性微乎其微(任何能够以这种方式运行您的脚本的人都应该有足够的能力知道存在 IP 检查)。不要担心边缘情况。如果您检查 127.x.x.x 和 ::1,您将涵盖所有合理的设置。
  • 感谢您缓解我的妄想症。
【解决方案2】:

没有。是否提供 remote_addr 取决于 Web 服务器。

撤回那个。..正在考虑 HTTP_REFERER。

它应该给你IP地址...是的。记住可能有代理。

【讨论】:

  • HTTP_REFERER 实际上取决于浏览器,而不是服务器。
【解决方案3】:

这可能通常不适用于来自 localhost 的连接,但您应该考虑代理。如果远端使用 HTTP 代理,$_SERVER['REMOTE_ADDR'] 将包含该代理的 IP 地址,而不是客户端本身的 IP 地址。

但是,如果它是禁用隐私设置的代理,那么您可能有机会使用以下 sn-p 获取客户端 IP:

// will be set by the proxy if no privacy is enabled:
if(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    return $_SERVER['HTTP_X_FORWARDED_FOR'];
} else if(isset($_SERVER['REMOTE_ADDR'])) {
    return $_SERVER['REMOTE_ADDR'];
}

但如果您的客户端使用启用了隐私的 HTTP 代理,那么您将没有机会获取客户端 IP。


安全提示(感谢@deceze)请注意,如果您依赖HTTP_X_FORWARDED_FOR 标头,攻击者很容易欺骗他们的IP。尽管使用其他技术也可以做到这一点,但使用 HTTP_X_FORWARDED_FOR 标头将非常容易。你被警告了。但无论如何,Web 应用程序不应该使用 IP 信息来确保安全,因此它只是一个旁注

【讨论】:

  • 1) 通过使用 X-Forwarded-For 标头而不是 REMOTE_ADDR,您为任何人提供了一种非常容易欺骗其 IP 地址的好方法;如果真的使用它除了REMOTE_ADDR作为元信息2)isset && !empty是多余的,只要!empty就可以了。
  • @deceze 非常感谢您的欺骗提示!我从来没有想过这个......到2.),这是不正确的,它们不一样:检查this fiddle
  • 我说isset && !empty 没有意义,并不是说它们是一样的。
  • @deceze isset && !empty 并非毫无意义。它检查数组索引是否存在并且它的值不是空字符串。
猜你喜欢
  • 2023-04-09
  • 2013-05-27
  • 1970-01-01
  • 2014-08-14
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 2012-08-26
相关资源
最近更新 更多