IP 地址解析库的不同实现导致应用存在安全隐患

先来看一个例子,对于 0177.0.0.1 这个 IP 地址不同的程序会解析出不同的结果:

curl

curl 0177.0.0.1 -v
* Rebuilt URL to: 0177.0.0.1/
*   Trying 177.0.0.1...
* TCP_NODELAY set

ping

$ ping 0177.0.0.1
PING 0177.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.059 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.084 ms
^C

可以看到,对于 0177.0.0.1 这个 IP 地址, curl 将它解析为 177.0.0.1 ,而 ping 却解析为了 127.0.0.1

之所以会有这种不一样的结果,是因为对于应该如何解析 IP 地址中数字前面的 0 并没有一个统一的标准, 有的程序将这种情况标记为无效 IP ,有些程序将 0xx 解析为 8 进制数字,有些程序将它解析为 10 进制数字。

正因为存在这种不统一的情况,也就导致应用程序对 IP 地址的校验逻辑存在安全隐患。

假设有一个服务的功能是访问用户输入的地址然后返回相应的响应信息,处于安全上的考虑, 会校验用户的输入,拦截访问服务内部 IP 的地址:

  1. 用户输入 http://0177.0.0.1:8080/path/to/secret
  2. 服务端的校验程序使用的 IP 解析库将地址中包含的 IP 地址解析为 177.0.0.1 ,然后放行了该请求
  3. 实际执行这个请求用户输入的服务,在请求这个地址时,使用的 IP 地址相关库将它解析为了 127.0.0.1 , 此时就会存在安全隐患,导致出现了非预期的结果。

基于 IP 黑名单的 ACL 或者过滤逻辑都有潜在的受这个问题影响的安全隐患, 这一问题的相关 CVE 可以参考【参考资料】中列出的部分 CVE 。

参考资料


Comments