dotnet-security-owasp 是一个面向 .NET 应用的 OWASP Top 10(2021)安全指导技能。每个类别都包含漏洞描述、.NET 特有风险、缓解代码示例以及常见陷阱。该技能是已弃用安全模式警告的规范归属方,涵盖 CAS、APTCA、.NET Remoting、DCOM 和 BinaryFormatter。
适用范围之外:认证/授权实现(API 级认证模式,如 Identity、OAuth/OIDC、JWT、passkeys、CORS)参见 dotnet-api-security 技能;Blazor 认证 UI(AuthorizeView、CascadingAuthenticationState)参见 dotnet-blazor-auth 技能;云特定安全服务(Azure Key Vault、AWS Secrets Manager)属于云专题;加密算法选择与密钥管理参见 dotnet-cryptography 技能;配置绑定与 Options 模式参见 dotnet-csharp-configuration 技能。交叉引用:机密处理参见 dotnet-secrets-management,密码学最佳实践参见 dotnet-cryptography,安全编码约定参见 dotnet-csharp-coding-standards。
A01 失效的访问控制:用户越权访问他人数据、提升权限或绕过访问检查。.NET 风险包括控制器/终结点缺少 [Authorize] 特性、不安全的直接对象引用(IDOR,从路由参数取用户 ID 而未校验归属)、CORS 配置错误允许非预期来源。缓解方式:全局应用授权后再显式放开;采用基于资源的授权防止 IDOR;将 CORS 限制为已知来源。陷阱:AllowAnyOrigin() 与 AllowCredentials() 组合会在运行时被 ASP.NET Core 拒绝,但 SetIsOriginAllowed(_ => true) 配合 AllowCredentials() 会静默允许所有来源,切勿使用该模式。
A02 加密失败:因加密薄弱或缺失导致敏感数据暴露,如明文存储、弃用算法或密钥管理不当。.NET 风险包括用 MD5/SHA1 哈希密码、在 appsettings.json 中明文存储带密码的连接字符串、通过 HTTP 传输敏感数据、使用 DES/RC2 加密。缓解方式:强制 HTTPS 与 HSTS;切勿在 appsettings.json 中存储机密,应使用用户机密或环境变量;使用数据保护 API 对应用数据做对称加密。算法选择(AES-GCM、RSA、ECDSA)与密钥派生参见 dotnet-cryptography 技能。
A03 注入:不可信数据作为命令或查询的一部分发送给解释器,包括 SQL 注入、命令注入、LDAP 注入和跨站脚本(XSS)。.NET 风险包括 SQL 查询字符串拼接、用未净化输入调用 Process.Start、在 Razor 页面中将用户输入渲染为原始 HTML。缓解方式:始终使用参数化查询,EF Core 通过 LINQ 默认参数化,需要原始 SQL 时使用 FromSqlInterpolated;绝不将用户输入拼接到 SQL;Razor 默认编码输出,仅在可信且已净化时使用 @Html.Raw(),Minimal API 返回类型化结果而非原始字符串;避免用用户输入调用 Process.Start,无法避免时使用允许列表校验。陷阱:FromSqlRaw 配合字符串拼接会绕过参数化,应始终使用 FromSqlInterpolated 或向 FromSqlRaw 传 SqlParameter 对象。
A04 不安全设计:设计模式缺陷无法仅靠实现修复,如缺少速率限制、缺乏纵深防御、资源消耗不受限。.NET 风险包括 API 没有速率限制、无限制文件上传、状态变更操作缺少防伪令牌。缓解方式:使用内置中间件做速率限制(.NET 7+);为 Minimal API 添加防伪(.NET 8+),表单绑定终结点自动校验,JSON 终结点需显式调用 RequireAntiforgery()。陷阱:UseRateLimiter() 必须在 UseRouting() 之后、MapControllers()/MapGet() 之前调用才能正确生效。
A05 安全配置错误:不安全的默认配置、不完整配置、开放的云存储、启用了不必要的功能、详细的错误消息。.NET 风险包括生产环境使用详细异常页(UseDeveloperExceptionPage)、默认 Kestrel 设置暴露服务器头、遗留启用的调试终结点、缺少安全头。缓解方式:移除服务器标识头(在 Build 前配置);生产环境使用通用错误处理器而非堆栈跟踪,并启用 HSTS;通过中间件添加安全头;限制请求体大小防止资源耗尽(在 Build 前配置)。陷阱:UseDeveloperExceptionPage() 会泄露源代码路径和堆栈跟踪,务必用 IsDevelopment() 门控,绝不在生产或预发布环境启用。
A06 易受攻击和过时的组件:使用存在已知漏洞的组件、不受支持的框架或未修补的依赖项。.NET 风险包括运行在已停止支持的 .NET 版本、含已知 CVE 的 NuGet 包、未审计的传递依赖漏洞。缓解方式:在 Directory.Build.props 或 csproj 中启用 NuGet 审计;用命令审计 NuGet 包已知漏洞并包含传递依赖;保持包更新;检查 .NET SDK/运行时支持状态。陷阱:NuGetAuditMode 默认为 direct,除非设为 all,否则传递依赖漏洞会被隐藏,CI 中应始终使用 all。
A07 身份识别和认证失败:弱认证机制、凭据填充、会话固定、缺少多因素认证。.NET 风险包括默认 Identity 密码策略过弱、会话 Cookie 缺少 Secure/SameSite 属性、缺少账户锁定配置。缓解方式:配置强 Identity 密码与锁定策略;配置安全 Cookie。陷阱:CookieSecurePolicy.SameAsRequest 允许开发环境通过 HTTP 发送 Cookie,这在开发中没问题;但生产环境在终止 TLS 的反向代理后,应用看到的是 HTTP,Cookie 会以不安全方式发送。生产环境应始终使用 CookieSecurePolicy.Always 并配置转发头。
A08 软件和数据完整性失败:代码和基础设施未防止完整性违规,如未签名包、不安全的 CI/CD 管道、反序列化不可信数据。.NET 风险包括使用 BinaryFormatter 反序列化(可导致任意代码执行)、接受来自不可信源的未签名 NuGet 包、缺少包源映射。缓解方式:在 nuget.config 中配置 NuGet 包源映射,仅允许来自可信源的包;绝不使用 BinaryFormatter,改用 System.Text.Json;二进制序列化需求可用 MessagePack 或 Protobuf。陷阱:包源映射遵循最具体模式优先,MyCompany.* 优于 * 通配符;应始终为内部包定义具体模式以防依赖混淆攻击。
A09 安全日志和监控失败:对安全相关事件记录不足、缺乏入侵监控、无法检测和响应活跃攻击。.NET 风险包括未记录认证失败、敏感操作缺少审计轨迹、明文记录敏感数据(密码、令牌)。缓解方式:使用结构化日志记录安全事件;绝不记录敏感数据,应脱敏凭据和 PII;配置日志过滤排除敏感路径;使用 IHttpLoggingInterceptor(.NET 8+)脱敏请求/响应头。
A10:源资料在 A09 之后中断,未提供该类别内容。