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

如何验证ASP.NET Core 7 API输入的System.Uri安全性?

CallbackUrl安全验证补充与可信域名存储方案

一、强化CallbackUrl的安全验证

现有的基础验证还不够全面,建议补充以下几项检查,彻底防范恶意或无效URL:

  • 强制HTTPS协议:确认令牌是敏感数据,必须通过HTTPS传输,避免明文泄露

    if (url.Scheme != Uri.UriSchemeHttps)
    {
        return BadRequest("Callback URL必须使用HTTPS协议");
    }
    
  • 限制合法端口:禁止使用SSH、远程桌面等高危端口,只允许业务常用的HTTPS端口

    var allowedPorts = new HashSet<int> { 443, 8443 }; // 可根据业务调整
    if (!allowedPorts.Contains(url.Port) && url.Port != -1) // Port=-1对应协议默认端口
    {
        return BadRequest("Callback URL使用了未授权的端口");
    }
    
  • 禁止预存参数/片段:防止恶意客户端提前注入参数,干扰后续确认令牌的拼接逻辑

    if (!string.IsNullOrEmpty(url.Query) || !string.IsNullOrEmpty(url.Fragment))
    {
        return BadRequest("Callback URL不能包含查询参数或锚点片段");
    }
    
  • 校验主机名合法性:确保主机是有效的DNS域名或IP地址,避免畸形URL绕过验证

    var hostType = Uri.CheckHostName(url.Host);
    if (hostType == UriHostNameType.Unknown)
    {
        return BadRequest("Callback URL的主机名格式无效");
    }
    

二、可信域名存储方案选型

关于将URL主机与可信列表对比的需求,两种方案各有优劣,按需选择:

硬编码方案

  • 适合场景:可信客户端数量极少(1-2个)、域名长期固定不变
  • 优势:代码简单,无需数据库依赖,性能无损耗
  • 实现示例:
    var trustedDomains = new HashSet<string> { "client-a.com", "client-b.org" };
    if (!trustedDomains.Contains(url.Host))
    {
        return BadRequest("Callback URL主机不在可信名单内");
    }
    
  • 缺点:域名变更必须重新部署API,灵活性差

数据库动态读取方案

  • 适合场景:可信客户端较多、域名需要频繁添加/修改
  • 优势:无需部署即可更新可信域名,支持后台动态管理
  • 优化建议:搭配分布式缓存(如Redis)减少数据库查询压力,缓存有效期设为1-2小时即可
  • 简化实现示例:
    // 注入数据库上下文与缓存服务
    private readonly AppDbContext _dbContext;
    private readonly IDistributedCache _cache;
    
    public TestController(AppDbContext dbContext, IDistributedCache cache)
    {
        _dbContext = dbContext;
        _cache = cache;
    }
    
    [HttpPost]
    public async Task<IActionResult> RegisterNewUser([FromBody] RegisterUserResource resource)
    {
        // ... 其他验证逻辑
    
        var cacheKey = "TrustedDomainsList";
        var cachedDomains = await _cache.GetStringAsync(cacheKey);
        HashSet<string> trustedDomains;
    
        if (cachedDomains == null)
        {
            // 从数据库读取并缓存
            trustedDomains = new HashSet<string>(await _dbContext.TrustedDomains.Select(t => t.Domain).ToListAsync());
            await _cache.SetStringAsync(cacheKey, JsonSerializer.Serialize(trustedDomains), 
                new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1) });
        }
        else
        {
            trustedDomains = JsonSerializer.Deserialize<HashSet<string>>(cachedDomains);
        }
    
        if (!trustedDomains.Contains(url.Host))
        {
            return BadRequest("Callback URL主机不在可信名单内");
        }
    
        // ... 用户注册与邮件发送逻辑
        return Ok();
    }
    

内容的提问来源于stack exchange,提问作者Bob.at.Indigo.Health

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 08:43:13