首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET 獲取客戶端 IP 的偽造風險與防範:X-Forwarded-For 頭部不可信

     編輯:ASP.NET 基礎

常見但危險的代碼

string GetClientIP()
{
    if (Request.ServerVariables["HTTP_VIA"] != null)
        return Request.ServerVariables["HTTP_X_FORWARDED_FOR"].Split(',')[0];
    else
        return Request.ServerVariables["REMOTE_ADDR"];
}

風險分析

  • HTTP_X_FORWARDED_FOR、HTTP_VIA、HTTP_CLIENT_IP 均來自客戶端發送的 HTTP 請求頭,完全可控、可偽造。
  • 攻擊者使用瀏覽器插件(如 Modify Headers)、curl、Postman 即可任意設置:
    X-Forwarded-For: 1.2.3.4
  • REMOTE_ADDR 是 TCP 連接的源 IP(由 Web 服務器從 Socket 獲取),無法直接偽造(偽造將導致無法建立連接、收不到響應)。

正確獲取策略

  1. 無反向代理:直接用 Request.UserHostAddress (即 REMOTE_ADDR)。
  2. 有已知可信代理(Nginx/IIS ARR/Azure Front Door/CDN):
    • 在代理層配置:proxy_set_header X-Real-IP $remote_addr;、proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    • 應用層只信任來自受信任代理 IP 段的請求頭:
      var forwarded = Request.Headers["X-Forwarded-For"];
      var realIp = Request.Headers["X-Real-IP"];
      // 驗證 Request.ServerVariables["REMOTE_ADDR"] 是否在受信代理白名單中
      if (IsTrustedProxy(Request.UserHostAddress))
          return !string.IsNullOrEmpty(realIp) ? realIp : forwarded?.Split(',')[0].Trim();
      else
          return Request.UserHostAddress;
  3. ASP.NET Core 內置中間件:
    // Startup.cs
    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
        options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("10.0.0.0"), 8)); // 信任內網代理
        options.KnownProxies.Add(IPAddress.Parse("192.168.1.100")); // 具體代理 IP
    });
    app.UseForwardedHeaders(); // 必須在 UseAuthentication 之前
    
    // 控制器中
    var ip = HttpContext.Connection.RemoteIpAddress; // 已經是真實客戶端 IP

安全清單

  • ❌ 盲目信任 X-Forwarded-For 用於權限控制、審計日志、風控決策。
  • ✅ 在網關/負載均衡層剝離並重寫頭部,應用層只讀取經過驗證的頭部。
  • ✅ 記錄 REMOTE_ADDR、X-Forwarded-For、User-Agent 完整鏈路,便於事後審計。
  • ✅ 使用 HttpContext.Connection.RemoteIpAddress (Core) 或經過驗證的中間件。

總結

HTTP 頭部不可信是網絡編程鐵律。獲取真實客戶端 IP 的正確姿勢是:基礎設施層負責傳遞真實 IP,應用層只信任經過基礎設施驗證的數據。任何直接讀取請求頭作為客戶端 IP 的代碼,都是安全漏洞。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved