You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何防止修改请求X-Real-IP后AspNetCoreRateLimit限流规则重置的安全问题

AspNetCoreRateLimit X-Real-IP伪造限流失效修复方案

漏洞根源

当前配置下AspNetCoreRateLimit会优先读取X-Real-IP请求头的值作为客户端IP做限流计数,未校验该请求头的来源是否可信,攻击者可随意修改这个请求头绕过限流规则。

修复方案

  • 方案1:配置可信反向代理规则(推荐,适用于服务前置Nginx/负载均衡的场景)
    在注册AspNetCoreRateLimit中间件之前,先配置ASP.NET Core自带的转发头中间件,仅信任指定代理服务器传递的IP头:
// 需放在所有中间件注册逻辑的最顶部
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedFor | Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedProto;
    // 添加你实际使用的反向代理的内网IP,只有这些代理传递的头才会被认可
    options.KnownProxies.Add(System.Net.IPAddress.Parse("192.168.1.100"));
    // 同网段代理可配置网段规则
    // options.KnownNetworks.Add(new Microsoft.AspNetCore.HttpOverrides.IPNetwork(System.Net.IPAddress.Parse("192.168.1.0"), 24));
    // 指定用X-Real-IP作为真实IP读取头,和你现有限流配置对应
    options.ForwardedForHeaderName = "X-Real-IP";
});

// 注册转发头中间件,必须放在AspNetCoreRateLimit中间件之前
app.UseForwardedHeaders();
// 原有的限流中间件注册
// app.UseIpRateLimiting();
  • 方案2:自定义IP解析逻辑(适用于需要灵活控制IP读取规则的场景)
    自定义IP解析器,仅当请求来自可信代理时才读取X-Real-IP头,否则直接取TCP连接原始IP:
public class CustomIpAddressParser : IIpAddressParser
{
    private readonly IIpAddressParser _defaultImpl;
    // 替换为你的可信代理IP列表
    private readonly List<IPAddress> _trustedProxies = new List<IPAddress> { IPAddress.Parse("192.168.1.100") };

    public CustomIpAddressParser(IIpAddressParser defaultImpl)
    {
        _defaultImpl = defaultImpl;
    }

    public IPAddress ParseIp(HttpContext httpContext)
    {
        var connectIp = httpContext.Connection.RemoteIpAddress;
        // 直连IP不是可信代理,直接用连接IP做限流,忽略请求头
        if (!_trustedProxies.Contains(connectIp))
        {
            return connectIp;
        }
        // 可信代理请求,走默认逻辑读取X-Real-IP
        return _defaultImpl.ParseIp(httpContext);
    }

    // 其余接口方法直接调用默认实现即可
    public bool IsIpInList(string clientIp, List<string> ipList) => _defaultImpl.IsIpInList(clientIp, ipList);
    public bool ValidateIp(string ipAddress) => _defaultImpl.ValidateIp(ipAddress);
}

注册自定义解析器替换默认实现:

builder.Services.AddSingleton<IIpAddressParser, CustomIpAddressParser>();
  • 方案3:禁用请求头IP读取(适用于服务直接对外暴露,无反向代理的场景)
    直接修改限流配置,把RealIpHeader设为空字符串即可,框架会直接读取TCP连接的原始IP作为客户端IP,不会解析任何请求头内容:
"IpRateLimiting": {
    "RealIpHeader": "",
    // 其余原有配置保持不变
    ...
}

注意:如果服务前置了反向代理不要直接使用方案3,否则会把代理IP识别为所有用户的IP,导致正常用户被误限流。

内容的提问来源于stack exchange,提问作者samin.hma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 00:24:00