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

如何修复.NET Core中的Server-Side Request Forgery (SSRF)漏洞?

缓解.NET Core中SSRF漏洞的方案

你的代码存在SSRF漏洞的核心原因是:urlContent由外部输入控制,直接用于构造服务器侧的请求地址。攻击者可以通过构造恶意URL,让你的服务器访问内部私有服务(比如本地数据库、内网API)或第三方恶意资源,引发安全风险。

以下是具体的缓解措施:

1. 强制使用域名/IP白名单

维护一个预先批准的域名或IP范围列表,只允许请求这些地址,这是最有效的防护手段:

// 根据业务需求定义白名单
private readonly HashSet<string> AllowedDomains = new HashSet<string> 
{ 
    "trusted-domain.com", 
    "api.allowed-service.net" 
};
private readonly List<IPAddressRange> AllowedIpRanges = new List<IPAddressRange> 
{
    IPAddressRange.Parse("203.0.113.0/24") // 仅允许业务需要的公网IP段
};

// 请求前验证逻辑
var targetUri = new Uri(TextHelper.RedirectUrlNull(urlContent));

// 验证域名
if (!AllowedDomains.Contains(targetUri.Host))
{
    throw new ArgumentException("请求域名未被授权");
}

// 解析IP并验证范围
var ipAddresses = await Dns.GetHostAddressesAsync(targetUri.Host);
foreach (var ip in ipAddresses)
{
    if (!AllowedIpRanges.Any(range => range.Contains(ip)))
    {
        throw new ArgumentException("请求IP未在允许范围内");
    }
}

注意:如果业务不需要访问内网,务必禁止所有私有IP段(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、127.0.0.0/8等)。可以使用IPAddressRange NuGet包简化IP范围判断。

2. 过滤受限IP和协议

即使不使用白名单,也要至少禁止访问本地回环地址、私有IP段,以及危险协议:

// 检查是否为受限IP
private bool IsRestrictedIp(IPAddress ip)
{
    return ip.IsLoopback || 
           IPAddressRange.Parse("10.0.0.0/8").Contains(ip) ||
           IPAddressRange.Parse("172.16.0.0/12").Contains(ip) ||
           IPAddressRange.Parse("192.168.0.0/16").Contains(ip) ||
           IPAddressRange.Parse("169.254.0.0/16").Contains(ip);
}

// 验证URL协议和IP
var targetUri = new Uri(TextHelper.RedirectUrlNull(urlContent));
if (targetUri.Scheme != Uri.UriSchemeHttp && targetUri.Scheme != Uri.UriSchemeHttps)
{
    throw new ArgumentException("仅允许HTTP/HTTPS协议");
}

var ipAddresses = await Dns.GetHostAddressesAsync(targetUri.Host);
if (ipAddresses.Any(IsRestrictedIp))
{
    throw new ArgumentException("禁止访问受限地址");
}

3. 限制HttpClient的行为

禁用自动重定向(防止攻击者通过重定向绕过验证),并限制请求资源大小:

var handler = new HttpClientHandler
{
    AllowAutoRedirect = false,
    MaxRequestContentBufferSize = 1024 * 1024 // 限制最大请求大小为1MB
};
using var httpClient = new HttpClient(handler);

// 后续请求逻辑...

额外建议:不要每次请求都创建新的HttpClient,通过DI注入单例实例,避免套接字耗尽问题。

4. 清理并验证输入URL

除了Uri.EscapeUriString,还要清理可能用于绕过验证的特殊字符,确保URL是合法绝对地址:

// 清理危险字符
urlContent = urlContent.Replace("@", "").Replace("%00", "").Trim();

var targetUri = new Uri(TextHelper.RedirectUrlNull(urlContent));
// 确保是绝对URI,防止相对路径被利用
if (!targetUri.IsAbsoluteUri)
{
    throw new ArgumentException("必须提供绝对URL");
}

总结

优先采用白名单机制,结合IP过滤、协议限制和输入清理,能有效防范SSRF漏洞。所有验证逻辑必须在发送请求前执行,不要依赖客户端的输入验证。

内容的提问来源于stack exchange,提问作者Samuel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 13:47:43