Broken access control: .NET provides [Authorize] and policies.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | // ====================================================================== // Q: OWASP Top 10: what does .NET protect you from, and where must you be // careful? // // - Broken access control: .NET provides [Authorize] and policies. Be careful // with IDOR (Q1), ownership checks and tenant filters. // - SQL injection: LINQ / EF Core generates parameters. Be careful with // FromSqlRaw or ADO.NET with string concatenation. // - XSS: Razor HTML-encodes output. Be careful with @Html.Raw, MarkupString in // Blazor, and set a Content-Security-Policy. // - CSRF: antiforgery tokens in Razor forms. APIs with cookie auth need SameSite // and antiforgery. Bearer tokens in the header are not affected. // - Mass assignment: model binding. Be careful with binding directly to an EF // entity instead of a DTO. // - SSRF: nothing automatic. User-supplied URLs (e.g. a webhook URL) need an // allowlist and must not reach internal IPs. // - Security misconfiguration: the templates give you HTTPS and HSTS. Be careful // with CORS AllowAnyOrigin, the developer exception page in production, and // secrets in appsettings.json. // - Vulnerable components: dotnet list package --vulnerable, NuGet audit. Use // Dependabot / Renovate and keep the runtime and base images updated. // ====================================================================== // SQL injection db.Products.FromSqlRaw($"SELECT * FROM products WHERE name = '{name}'"); // WRONG db.Products.FromSql($"SELECT * FROM products WHERE name = {name}"); // RIGHT: becomes a parameter // Mass assignment / overposting // WRONG: the client can also send "creditLimit": 1000000 public async Task<IActionResult> Update(Customer customer) { db.Update(customer); await db.SaveChangesAsync(); return Ok(); } // RIGHT: a DTO with only the fields that are allowed to change public record UpdateCustomerRequest(string Name, string Phone); |