pkey
.Net

OWASP Top 10 (2025) Explained with ASP.NET Core — Real Examples, Bad Code, and Secure Fixes

Introduction

The OWASP Top 10 ASP.NET Core is the most important baseline for modern web application security. It represents real-world vulnerabilities observed in enterprise systems, SaaS platforms, APIs, and microservices.

For developers working with ASP.NET Core, these risks are not theoretical — they exist in everyday code: controllers, LINQ queries, JWT authentication, configuration, error handling, and external integrations.

A typical application may look clean:

  • Dependency Injection ✔
  • Entity Framework ✔
  • JWT ✔
  • Docker ✔

But still be vulnerable.


🔴 Image — Request Security Flow

OWASP Top 10 ASP.NET Core
OWASP Top 10 ASP.NET Core
OWASP Top 10 ASP.NET Core

6

User → Validation → Authentication → Authorization → Business Logic → Database

In OWASP Top 10 ASP.NET Core most vulnerabilities happen when one of these steps is skipped.


1. Broken Access Control

❌ Example 1 — Missing Ownership Check

C#
[HttpGet("{id}")]
public async Task<IActionResult> GetOrder(int id)
{
    var order = await db.Orders.FindAsync(id);
    return Ok(order);
}

Attack

GET /orders/1
GET /orders/2
GET /orders/3

User reads data.


❌ Example 2 — Admin Endpoint Without Role Check

C#
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteUser(int id)
{
    var user = await db.Users.FindAsync(id);
    db.Users.Remove(user);
    await db.SaveChangesAsync();
    return Ok();
}

✅ Fix

C#
[Authorize(Roles = "Admin")]
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteUser(int id)
{
    ...
}

✅ Secure Ownership Check

C#
var userId = User.FindFirst("sub")?.Value;

var order = await db.Orders
    .Where(o => o.Id == id && o.UserId == userId)
    .FirstOrDefaultAsync();

2. Injection

🔴 Image — SQL Injection


❌ Example 1 — Raw SQL

C#
var sql = "SELECT * FROM Users WHERE Email = '" + email + "'";
var users = db.Users.FromSqlRaw(sql).ToList();

❌ Example 2 — Command Injection

C#
Process.Start("cmd.exe", "/c ping " + host);

✅ Fix 1 — LINQ

C#
var user = await db.Users
    .FirstOrDefaultAsync(x => x.Email == email);

✅ Fix 2 — Sanitization + Whitelist

C#
if (!Regex.IsMatch(host, @"^[a-zA-Z0-9.-]+$"))
    return BadRequest();

3. Cryptographic Failures

🔴 Image — Password Security

https://images.openai.com/static-rsc-4/XvO1TEjml7t3F9OJbCASAZgTqV8IMj4kkay1IVIGJJsz4XXt-t_CZ_wjWS1sEItn5eJzVSTxlxrmG_nqoeBlkAvC0b2zo09CZmA8IthY0EiQ7zsjs4oPJccm94XODcWfGYNgM-o4R5ZilJcAHLcws4fhsrJfzl6f0Wvc8460acUuBuvFUT19JS3mzwNFXgCg?purpose=fullsize
https://images.openai.com/static-rsc-4/7KkhkLQxCv1XOrYv6ihDch2UnyVtBKfkiaYjtVwrQdBHWUJVJRGYLFy7j42anoUdyepMSGsDeVfUhOCQvzgMoaEYWaWHKENh0_P6rQuKNhFOvrgR8bYqamI-N9Ag9cO7jg6I9U_0Nfqivzr_sYOKn_xnbIzePWwxJ2-KzcYvMePQjwySIH0gbIxVX0-gdgE8?purpose=fullsize
https://images.openai.com/static-rsc-4/-EQ9uQLS354iV_b8XsYMUjZ2woMsE38fYDSSggDycYXUhbEUMWln25LlLeTYCp94tqSQowqE2rT8K-Di1tHZjH44Z2dft7Mx-ogM-n6mcFrV-g-yVFnL16M8F2-rXXk12eCZxtGI-x--pK-CFYPHNo1FR3-kAoB3Y4mWwbfqm_hozKS285KH1kfeCsH0J0O4?purpose=fullsize

6


❌ Example 1 — Plain Password

C#
user.Password = password;

❌ Example 2 — Weak Hash

C#
user.Password = SHA1(password);

✅ Fix 1 — ASP.NET Identity

await userManager.CreateAsync(user, password);

✅ Fix 2 — Data Protection API

C#
var protector = dataProtectionProvider.CreateProtector("tokens");
var encrypted = protector.Protect("sensitive-data");

4. Insecure Design


❌ Example 1 — No Rate Limit

C#
[HttpPost("login")]
public IActionResult Login(LoginDto dto)
{
    return Ok(authService.Login(dto));
}

❌ Example 2 — No Business Rules

User can order negative quantity:

C#
order.Quantity = -100;

✅ Fix 1 — Rate Limiting

C#
builder.Services.AddRateLimiter(options =>
{
    options.AddFixedWindowLimiter("login", opt =>
    {
        opt.PermitLimit = 5;
        opt.Window = TimeSpan.FromMinutes(1);
    });
});

✅ Fix 2 — Domain Validation

C#
if (quantity <= 0)
    throw new ArgumentException("Invalid quantity");

5. Security Misconfiguration


❌ Example 1 — Swagger Public

C#
app.UseSwagger();

❌ Example 2 — Detailed Errors

C#
app.UseDeveloperExceptionPage();

✅ Fix

C#
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
    app.UseSwagger();
}

✅ Security Headers

C#
app.Use(async (ctx, next) =>
{
    ctx.Response.Headers.Add("X-Content-Type-Options", "nosniff");
    ctx.Response.Headers.Add("X-Frame-Options", "DENY");
    await next();
});

6. Vulnerable Components


❌ Example 1 — Old NuGet

BAT (Batchfile)
dotnet add package Newtonsoft.Json --version 9.0.1

❌ Example 2 — No Dependency Scan

CI without security check.


✅ Fix

BAT (Batchfile)
dotnet list package --vulnerable

✅ CI Check

YAML
- name: Check vulnerabilities
run: dotnet list package --vulnerable

7. Authentication Failures

🔴 Image — JWT Flow

https://images.openai.com/static-rsc-4/2-JawdroBGoyycaRZZ14_I6Xrqnw0cNRovHyqWZX7yok5t1IQC7cSAHcACHjd-0QD71jwp30X7D2cqx31zyjXHg3OrG7JV0omp4YAW7drfnvMYO9Ue04JSe8aun9OFkiN2ycB1QtAsAjLJBKJU-D7YeobzhJgT-5j9pcAFlze-Xavs30Zh1bkBex89NAewkG?purpose=fullsize
https://images.openai.com/static-rsc-4/4u7ET65cYNOLxkaj8fWtk-_H4JaEluFOR3DaRqGp5A2oZBANcv8pEVeGi_vpia7gWNb03WcxU_aq9PzF0jxo0cgUIGWfgAkGJdrGtCkadLizy-mFcSLAe4BOKgeTaFtl_6a-vCgkA18-bsP8sLS0z3b3ioc7Iv_ZwWJBoV8h4Sh5NGdTx_I9tPwvR1lMicRL?purpose=fullsize
https://images.openai.com/static-rsc-4/scEnuI7p1QqY7Tpxt82Uq3XhZEj9xKCcqdp95WuEMPwWz5OyUdW4eeVWAAazkCS_uw_keug7F0fyCL6yD2P7M5iUbzHrzjFOKDm0wmNPh7u7wq0G75Ok_3Q7Zm6FkffK4cYDkkoUjxiGcpZWjX72LyUq6DJeGHVvo_fiPRgLVC76y-DzS8iIzVaZMJA6uKMV?purpose=fullsize

6


❌ Example 1 — No Validation

YAML
ValidateIssuer = false;

❌ Example 2 — No Expiration

Token never expires.


✅ Fix

YAML
ValidateLifetime = true;
ClockSkew = TimeSpan.Zero;

✅ Secure Cookie

C#
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;

8. Software/Data Integrity Failures


❌ Example 1 — Auto Deploy

OWASP Top 10 ASP.NET Core CI deploys on push without review.


❌ Example 2 — Untrusted Packages

BAT (Batchfile)
dotnet add package random-lib

✅ Fix

✔ Code review required
✔ Signed packages
✔ Private NuGet feed

9. Logging & Monitoring Failures


❌ Example 1

C#
catch { }

❌ Example 2

No logs for login attempts.


✅ Fix

C#
logger.LogWarning("Failed login for {Email}", email);

✅ Central Logging

C#
builder.Host.UseSerilog();

10. SSRF (Server-Side Request Forgery)


❌ Example 1

C#
return await httpClient.GetStringAsync(url);

❌ Example 2

Calling internal services via user input.


✅ Fix — Whitelist

C#
var allowed = new[] { "api.partner.com" };

✅ Fix — DNS/IP Check

C#
var ip = Dns.GetHostAddresses(uri.Host);

if (ip.Any(i => IPAddress.IsLoopback(i)))
    return BadRequest();

🔥 Enterprise Security Checklist

✔ Per-user data filtering
✔ Strong JWT validation
✔ Rate limiting
✔ Secure headers
✔ Dependency scanning
✔ Logging & alerting
✔ No raw SQL
✔ Input validation
✔ External call whitelist
✔ CI/CD security gates

Final Thoughts

OWASP Top 10 ASP.NET Core Security is not a feature — it is a continuous process.

Most real vulnerabilities are not complex:

  • missing WHERE clause
  • missing validation
  • wrong config

The OWASP Top 10 helps you avoid exactly those mistakes.

Source

https://github.com/rafalkukuczka/OwaspTop10AspNetCoreDemo

References

https://owasp.org/www-project-top-ten

More Info

We implement this in real production systems.
If you need help → contact us

Contact