如何检测连接是否经CloudFlare?$_SERVER变量是否需过滤使用?
嘿,我来帮你把Cloudflare IP检测和$_SERVER变量安全的问题讲清楚~
一、正确检测Cloudflare请求并获取真实客户端IP
直接依赖$_SERVER["HTTP_CF_CONNECTING_IP"]是不安全的,因为这个请求头可以被伪造。正确的做法是先验证请求确实来自Cloudflare的官方IP段,再使用这个头的值:
- 先获取直接连接到你服务器的IP(这个是TCP层面的源IP,无法通过请求头伪造):
$connectionIp = $_SERVER['REMOTE_ADDR']; - 验证这个IP是否属于Cloudflare的合法IP范围(Cloudflare会定期更新IP列表,你可以把这些IP段存在配置里,或者定期同步最新的):
比如Cloudflare的IPv4段示例(记得替换为官方最新的):
你可以用PHP的103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 // 更多IPv4和IPv6段请参考Cloudflare官方更新ip2long或者专门的IP处理工具,判断$connectionIp是否在这些段内。 - 如果验证通过,再取
HTTP_CF_CONNECTING_IP作为真实客户端IP;否则直接用$connectionIp:// 示例:假设已提前定义Cloudflare合法IP段数组 $cloudflareIps = [/* 填入Cloudflare的IP段 */]; $isFromCloudflare = false; // 这里编写验证$connectionIp是否在$cloudflareIps中的逻辑 if ($isFromCloudflare && isset($_SERVER["HTTP_CF_CONNECTING_IP"])) { $clientIp = $_SERVER["HTTP_CF_CONNECTING_IP"]; // 额外验证IP格式,避免异常值 if (!filter_var($clientIp, FILTER_VALIDATE_IP)) { $clientIp = $connectionIp; } } else { $clientIp = $connectionIp; }
二、$_SERVER变量的安全性与过滤
核心结论:
$_SERVER中以HTTP_开头的变量(比如HTTP_CF_CONNECTING_IP)完全由客户端控制,可以随意伪造,绝对不能直接信任,必须先验证来源再使用。$_SERVER['REMOTE_ADDR']是TCP连接的源IP,无法通过请求头伪造,相对安全,但如果你的服务器前面还有其他代理,需要对应调整验证逻辑。
必须做的防护步骤:
- 来源验证:只有确认请求来自Cloudflare(通过
REMOTE_ADDR匹配Cloudflare IP段),才使用HTTP_CF_CONNECTING_IP。 - 格式验证:即使是Cloudflare发来的
HTTP_CF_CONNECTING_IP,也要用filter_var($ip, FILTER_VALIDATE_IP)验证它是合法的IP格式,避免恶意构造的无效值。 - 禁止直接使用未验证的HTTP头:如果跳过来源验证,攻击者可以随便设置
HTTP_CF_CONNECTING_IP来冒充任何IP,这会导致身份验证、日志记录等业务逻辑出现严重安全问题。
内容的提问来源于stack exchange,提问作者mkaminski
相关产品推荐
相关产品推荐

