【问题标题】:How secure is to assume that if $_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR'], is the server the one making the request?假设如果 $_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR'] 是服务器发出请求的安全性如何?
【发布时间】:2013-06-19 19:42:52
【问题描述】:

嗯,这个问题说明了一切,我想知道,这样的比较有多安全:

if ($_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR']) {
    // yeah, it's the server, go ahead do this.
}

我问的原因是识别来自服务器本身的一些 web api 调用。

我知道$_SERVER['REMOTE_ADDR'] 可以被欺骗来运行请求,但不能从中获取结果。如果是这种情况,例如在讨论 Rest 时,例如 GET 请求不会出现问题,但 DELETE 请求呢,不需要解析来自服务器的响应。
如果上述说法正确,是否意味着您不应该相信后面的比较?
有哪些替代方案(让我们从这里排除 CLI)?

【问题讨论】:

  • 使用某种密码怎么样?
  • 可以安全地假设如果$_SERVER['REMOTE_ADDR']127.0.0.1$_SERVER['SERVER_ADDR'],则请求来自服务器本身,但如果您不是服务器中唯一运行脚本的人或服务器正在运行像 Squid 这样的代理服务,你可能会遇到麻烦。正如 TimWolla 建议的那样,在某些身份验证层中更多地依赖应该是合适的。
  • -- TimWolla 是的,你说得有道理,检查密码也会更聪明。 -- Havenard - 好的,但是攻击者不能将它的 ip 欺骗为 127.0.0.1 因此它会欺骗机制吗?
  • 您不能使用欺骗性 IP 来稳定 TCP 会话或与任何服务器的任何双向通信。您不必在这里担心。
  • @Havenard - 好的,感谢您清除它:)

标签: php security ip-address


【解决方案1】:

我会说它是安全的,只要它不执行任何有害的操作。

如果有人伪造了 IP 地址,那么他们将不会收到响应,因为服务器会将响应发送给自己而不是攻击者。

因此显示堆栈跟踪应该没问题,但是如果您基于此执行了一些特殊操作,那么攻击者可能会在没有看到响应的情况下造成破坏。

【讨论】:

    【解决方案2】:

    最好的解决方案是使用安全密码。

    只要您的检查只允许正确的密码,您就不必担心伪造的 IP 地址或其他可能的不安全检查。

    if ($_GET['password'] === 'my_password') {
        // code
    }
    

    考虑使用secure compare function 来避免定时攻击。

    【讨论】:

      【解决方案3】:

      这不是一个安全的假设。正如@TimWolla 所提到的,有一些请求,其中$_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR'] 将是true 而没有来自服务器的请求。还要考虑 LAN 上的其他设备。考虑这种情况:

      • 您的服务器的本地 IP 为 192.168.1.2
      • 您网络上的恶意用户的本地 IP 为 192.168.1.3
      • 您的网络的公共 IP 为 1.2.3.4

      如果您的服务器正在侦听1.2.3.4:80,则恶意客户端向1.2.3.4:80 的请求将具有$_SERVER['REMOTE_ADDR'] = '1.2.3.4'

      因此,如果只有您的服务器需要能够访问此功能,则不应将此端口公开暴露给互联网。您应该在另一个端口(比如 81)上配置一个单独的 apache 虚拟主机,并为该端口设置防火墙,以便它拒绝所有非来自服务器本身的传入连接。

      【讨论】:

      • 是的,没有。 TCP 不是这样工作的……REMOTE_ADDR 是需要响应的客户端的IP 地址。所以如果REMOTE_ADDR192.168.1.2,和服务端一样,那么请求来自服务端...这个是在设计TCP和IP的时候考虑的...
      • @ircmaxell 在我的假设情况下REMOTE_ADDRSERVER_ADDR 会不会相同,即使请求来自 LAN 上的另一个客户端?
      • 没有。 REMOTE_ADDR始终是 TCP 数据包的接收者。所以如果REMOTE_ADDR == SERVER_ADDR,要么是服务器出了问题(这可能会发生),要么是你的路由器被入侵了。无论哪种方式,这都不是常见的事情,也不是你应该依赖(或不依赖)的......
      猜你喜欢
      • 2017-01-03
      • 2021-03-12
      • 1970-01-01
      • 2011-06-14
      • 1970-01-01
      • 2011-10-24
      • 2012-09-23
      • 1970-01-01
      • 2011-05-14
      相关资源
      最近更新 更多