Secure By Design - The OWASP Top 10 Explained with Real Code Examples

Explore the OWASP Top 10 security risks with hands-on code examples in C# and Python. Learn how to secure your applications by design, and avoid the most common vulnerabilities.

The OWASP Top 10 outlines the most critical web application security risks. Each one is a window into how modern systems are compromised—and how you can prevent it. Below, we break down each risk with real ASP.NET Core code examples and suggest mitigation strategies.

A01: Broken Access Control
A01: Broken Access Control

Improper access checks allow users to perform unauthorized actions.

What is it?
When users can access resources or perform actions they shouldn’t be allowed to. This often includes horizontal or vertical privilege escalation and missing role validations.

Why it matters:
Attackers may gain access to sensitive data or unauthorized features, compromising confidentiality and control.

Real-world Example:
Instagram’s developer API allowed access to user contact info via incremental user IDs without access control.

[HttpGet("/admin/data")]
public IActionResult GetAdminData()
{
    return Ok("Sensitive admin data");
}
[Authorize(Roles = "Admin")]
[HttpGet("/admin/data")]
public IActionResult GetAdminData()
{
    return Ok("Sensitive admin data");
}
A02: Cryptographic Failures
A02: Cryptographic Failures

Sensitive data isn’t properly protected using encryption or hashing.

What is it?
Cryptographic failures occur when sensitive data is not properly protected in transit or at rest. This includes using weak algorithms, failing to encrypt data, or improperly storing passwords.

Why it matters:
Data breaches can expose personal, financial, or system data. Attackers may intercept unencrypted data or crack weak password hashes.

Real-world Example:
In 2019, Facebook admitted storing hundreds of millions of user passwords in plaintext, accessible to employees.

public void Register(string username, string password)
{
    var user = new User { Username = username, Password = password };
    _context.Users.Add(user);
    _context.SaveChanges();
}
public void Register(string username, string password)
{
    var hashedPassword = _passwordHasher.HashPassword(null, password);
    var user = new User { Username = username, Password = hashedPassword };
    _context.Users.Add(user);
    _context.SaveChanges();
}
A03: Injection
A03: Injection

Malicious input can trick the system into executing unintended commands or queries.

What is it?
Injection occurs when untrusted input is executed as part of a command or query. SQL injection is the most well-known example.

Why it matters:
Attackers can steal, modify, or delete data and potentially gain control of the application or host.

Real-world Example:
The 2017 Equifax breach was partly due to an injection vulnerability in Apache Struts, exposing sensitive data of over 140 million Americans.

🚨 Vulnerable Example (SQL Injection)
public IActionResult Search(string email)
{
    var sql = $"SELECT * FROM Users WHERE Email = '{email}'";
    var users = _context.Users.FromSqlRaw(sql).ToList();
    return Ok(users);
}
✅ Remediated Example
public IActionResult Search(string email)
{
    var users = _context.Users
        .Where(u => u.Email == email)
        .ToList();
    return Ok(users);
}
A04: Insecure Design
A04: Insecure Design

Lack of secure design patterns and controls in the system architecture.

What is it?
Security flaws resulting from missing or inadequate design patterns. Often a result of skipping threat modeling, misuse case analysis, or not defining security controls early in SDLC.

Why it matters:
Once in production, insecure design is hard to mitigate without major refactoring. Prevention is far cheaper than remediation.

Real-world Example:
Many API endpoints remain vulnerable due to assumptions made during initial design stages, including open-by-default configurations without auth checks.

🚨 Vulnerable Example (No Security Consideration)
[HttpPost("/transfer")]
public IActionResult TransferFunds(decimal amount, int accountId)
{
    _bank.Transfer(amount, accountId);
    return Ok("Transferred");
}
✅ Remediated Example
[Authorize]
[HttpPost("/transfer")]
public IActionResult TransferFunds(decimal amount, int accountId)
{
    var userId = GetUserId();
    if (!_bank.CanAccessAccount(userId, accountId)) return Forbid();
    _bank.Transfer(amount, accountId);
    return Ok("Transferred");
}
A05: Security Misconfiguration
A05: Security Misconfiguration

Misconfigured settings, headers, or unused services create vulnerabilities.

What is it?
Occurs when default settings are insecure, unnecessary features are enabled, or configurations are inconsistent across environments.

Why it matters:
These flaws are easy to exploit and often lead to full system compromise.

Real-world Example:
In 2017, Uber exposed private GitHub credentials that led to unauthorized S3 access due to misconfigured access controls.

🚨 Vulnerable Example
// Startup.cs
app.UseDeveloperExceptionPage();
✅ Remediated Example
if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}
A06: Vulnerable and Outdated Components
A06: Vulnerable and Outdated Components

Using old or insecure software libraries exposes applications to known attacks.

What is it?
Using libraries, frameworks, or components with known vulnerabilities can introduce risks even if your code is secure.

Why it matters:
Attackers often scan for known CVEs and exploit unpatched components. You’re only as strong as your weakest dependency.

Real-world Example:
The infamous Log4Shell vulnerability (CVE-2021-44228) in Log4j affected thousands of applications using an outdated logging library.

🚨 Vulnerable Example
// Outdated NuGet package
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
✅ Remediated Example
// Updated to secure version
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
A07: Identification and Authentication Failures
A07: Identification and Authentication Failures

Weak or missing authentication can lead to unauthorized access or impersonation.

What is it?
Flaws in identity verification, authentication logic, or session management, allowing attackers to compromise accounts or impersonate users.

Why it matters:
These vulnerabilities lead to account takeovers, privilege escalations, and impersonation attacks.

Real-world Example:
Slack suffered from an authentication bug in 2022 that exposed hashed passwords in telemetry due to poor session token logic.

🚨 Vulnerable Example
public IActionResult Login(string user, string pass)
{
    var result = _auth.TryLogin(user, pass);
    return result ? Ok("Logged in") : Unauthorized();
}
✅ Remediated Example
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(15);
options.Lockout.MaxFailedAccessAttempts = 5;
A08: Software and Data Integrity Failures
A08: Software and Data Integrity Failures

Assuming data or software is trustworthy without validation.

What is it?
Assuming software updates, CI/CD artifacts, or external data are safe without verification or integrity checks.

Why it matters:
Attackers can inject malicious code or tamper with update mechanisms, as seen in software supply chain attacks.

Real-world Example:
The SolarWinds attack injected malware into signed software updates, impacting thousands of companies.

🚨 Vulnerable Example
// Unverified script include
<script src="https://cdn.example.com/lib.js"> </script>
✅ Remediated Example
<script src="https://cdn.example.com/lib.js"
  integrity="sha384-abc123" crossorigin="anonymous"> </script>
A09: Security Logging and Monitoring Failures
A09: Security Logging and Monitoring Failures

Lack of logging and monitoring delays breach detection and response.

What is it?
Failure to log security events, monitor suspicious activity, or generate alerts can hinder breach detection and response.

Why it matters:
Without proper monitoring, incidents can remain undetected for weeks or months, increasing damage.

Real-world Example:
Equifax's 2017 breach went undetected for over two months due to lack of effective logging and alerting systems.

🚨 Vulnerable Example
try {
    DoSomething();
} catch (Exception) {
    // Ignored
}
✅ Remediated Example
try {
    DoSomething();
} catch (Exception ex) {
    _logger.LogError(ex, "Unexpected error");
    throw;
}
A10: Server-Side Request Forgery (SSRF)
A10: Server-Side Request Forgery (SSRF)

Allows attackers to make the server send requests to unintended destinations.

What is it?
SSRF vulnerabilities occur when an app fetches a URL controlled by the user, allowing attackers to reach internal services.

Why it matters:
Attackers can scan internal networks, access metadata services, or abuse trust relationships within cloud environments.

Real-world Example:
The 2019 Capital One breach exploited SSRF to retrieve AWS metadata, leading to credential leakage.

🚨 Vulnerable Example
public async Task Fetch(string url)
{
    var result = await _http.GetStringAsync(url); // Unsafe
    return Ok(result);
}
✅ Remediated Example
if (!url.StartsWith("https://api.trusted.com"))
    return BadRequest("Invalid URL");

var result = await _http.GetStringAsync(url);
return Ok(result);