OWASP Top 10 (2021)
A01: Broken Access Control
Users access resources outside their permission or modify other users' data. The most common security weakness in 2021.
Enforce server-side authorization on every endpoint. Apply default-deny. Use unguessable IDs (UUID/GUID). Check ownership on every resource to prevent IDOR. Never trust client-side role checks.
Wrong: GET /api/orders/123 only checks login. Right: validate order.UserId == currentUser.Id or role-based policy.
A02: Cryptographic Failures
Weak or wrong encryption of sensitive data (passwords, cards, PII) exposes it directly during a leak.
Hash passwords with bcrypt/argon2/scrypt (never MD5/SHA1). Use TLS 1.2+ everywhere. Encrypt sensitive fields at application level. Forbid weak algorithms (DES, RC4, MD5). Keep keys in KMS/Vault.
ASP.NET Core: PasswordHasher uses PBKDF2; for stronger, use Argon2id (Konscious.Security.Cryptography.Argon2 package).
A03: Injection (SQL, NoSQL, OS, LDAP)
When user input is concatenated into queries, attackers can execute arbitrary code via the database, file system or shell.
Always use parameterized queries/prepared statements. Avoid raw SQL in ORMs. Keep auto-escape on in template engines (HTML, email). Use argv arrays instead of shell for command calls. Validate input, encode output.
EF Core: db.Users.Where(u => u.Email == email) is safe; FromSqlRaw($"... WHERE email = '{email}'") is dangerous. Use FromSqlInterpolated. A04: Insecure Design
Security isn't bolted on; it starts in design. Without threat modeling, every feature opens new attack surface.
Apply STRIDE/abuse-case analysis to every new feature. Define data classification (public/internal/confidential). Secure defaults: deny by default, secure by default. Plan rate limiting and quotas in the design phase.
When designing password reset, plan token TTL, single-use, IP/rate limit, and old-session invalidation — not just 'send a token'.
A05: Security Misconfiguration
Default passwords, open directory listing, unnecessary HTTP methods, verbose errors — these gift attackers their work.
Disable detailed errors in production. Change/remove default credentials. Disable unused ports/features. Add security headers: HSTS, X-Content-Type-Options, X-Frame-Options/CSP, Referrer-Policy. Define narrow CORS.
ASP.NET Core: app.UseHsts(), app.UseHttpsRedirection(); add Content-Security-Policy to response headers; UseDeveloperExceptionPage only in Development.
A06: Vulnerable & Outdated Components
Using packages with known CVEs gives attackers ready exploits. Modern apps carry hundreds of transitive dependencies.
Automate dependency scanning (Dependabot, Renovate, npm audit, dotnet list package --vulnerable). Produce SBOMs. Update small and often; plan major upgrades. Remove unused dependencies.
Run dotnet list package --vulnerable --include-transitive in CI via GitHub Actions; fail build if findings > 0.
A07: Identification & Authentication Failures
Weak password policy, missing MFA, no brute-force protection, mishandled session IDs lead to account takeover.
Offer MFA by default or at least optional. Min 8+ char passwords, check against common-password list. Rate-limit login/register/forgot. Store session IDs in httpOnly+Secure+SameSite=Lax cookies. Invalidate session server-side on logout.
In ASP.NET Core Identity, enable Lockout (5 fails → 15 min lock), offer TwoFactorEnabled to users, set RequireUniqueEmail = true.
A08: Software & Data Integrity Failures
Pulling libraries from unverified sources, unsigned update mechanisms, weak CI/CD isolation — enable supply chain attacks.
Pin dependencies via lockfile (package-lock.json, packages.lock.json). Require signed NuGet packages. Use ephemeral CI secrets via GitHub OIDC/Azure Federated Identity. Reject webhooks that don't verify signatures.
In .csproj, set <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile> and <RestoreLockedMode>true</RestoreLockedMode>; least-privilege pipeline permissions.
A09: Security Logging & Monitoring Failures
Mean time to detect breaches is months. Without logs or alerts, you may never know an incident happened.
Emit structured logs for login success/failure, authz denials, critical data changes, admin actions. Don't log sensitive data. Centralize logs (ELK, Seq, Datadog, CloudWatch). Define alerts for abnormal activity.
Serilog + Seq: log login fails at Warning; alert to Slack/email if same IP exceeds 10 failed logins per minute.
A10: Server-Side Request Forgery (SSRF)
If your server fetches a user-supplied URL, attackers can reach internal services, cloud metadata endpoints (169.254.169.254), or admin panels.
Restrict user URLs to allowlisted domains. Resolve IPs and reject private/loopback ranges (defends DNS rebinding). Disable or control redirect-following in HTTP client. Limit egress via proxy/firewall.
Webhook delivery / link preview features are typical SSRF sources; before fetching, check IPAddress.Parse for IsPrivate/IsLoopback.