OWASP Top 10 in ASP.NET Core: what .NET protects you from and where to be careful

ASP.NET Core Interview Q&A November 13, 2026 csharp

Broken access control: .NET provides [Authorize] and policies.

csharp
 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);