今日新坑 k8s ingress HTTP_X_ORIGINAL_FORWARDED_FOR 头的坑

背景,在处理一个神奇的IP查询BUG时,发现有用户伪造IP地址,具体方案就是添加 x-forwarded-for 的头,达到伪造的目的,这个问题在之前已经处理过了,不过又出现了,可能和迁移到k8s有关系。

伪造方式:

curl -H"x-forwarded-for: 100.14.144.11, 14.2.2.4" "https://www.baidu.com"

服务端会收到如下内容:

$_SERVER[HTTP_X_ORIGINAL_FORWARDED_FOR]: 100.14.144.11, 14.2.2.4, 11.123.11.244
$_SERVER[HTTP_X_FORWARDED_FOR]: 100.14.144.11
$_SERVER[HTTP_X_REAL_IP]: 100.14.144.11

现实很残酷:HTTP_X_FORWARDED_FOR得到了一个错误的IP地址,而我需要的11.123.11.244IP则存在于HTTP_X_ORIGINAL_FORWARDED_FOR中。于是开始排查问题。

  1. 检查代理是否有单独设置变量【正常】
  2. 检查容器是否有设置变量【正常】
  3. 检查入口SLB和Nginx是否设置变量【正常】
  4. 检查Ingress是否有设置变量【不正常】 很不客气的设置了X-Original-Forwarded-For
  5. 检查Ingress使用错误IP的原因:set_real_ip_from 0.0.0.0/0;

于是问题找到,然后开始安心修BUG,几个项目一个一个替换HTTP_X_FORWARDED_FORHTTP_X_ORIGINAL_FORWARDED_FOR, 然后使用了变态的修正方案

<?php
if (isset($_SERVER['HTTP_X_ORIGINAL_FORWARDED_FOR'], $_SERVER['HTTP_X_FORWARDED_FOR'])
    && strpos($_SERVER['HTTP_X_ORIGINAL_FORWARDED_FOR'], $_SERVER['HTTP_X_FORWARDED_FOR']) !== false) {
    // 修正 HTTP_X_FORWARDED_FOR 不是原始值的问题
    $_SERVER['HTTP_X_FORWARDED_FOR_BACKUP'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
    $_SERVER['HTTP_X_FORWARDED_FOR'] = $_SERVER['HTTP_X_ORIGINAL_FORWARDED_FOR'];
}

当前还没有任何评论

写下你最简单的想法