Skip to content
7 min read·Lesson 6 of 10

Application Security and the OWASP Top 10

Understand the most common web vulnerabilities, how they happen, how to fix them, and how to bake security into the SDLC with SAST, DAST, and SCA.

Most modern attacks don't target the network or the OS — they target your code. Application security is the discipline of finding and fixing those vulnerabilities, ideally before attackers do.

The OWASP Top 10 (2021)

The Open Worldwide Application Security Project publishes a top-10 list of web application risks every few years. The 2021 edition:

  1. A01 Broken Access Control — users can act as other users, escalate privileges, or access unauthorised data. Mitigation: deny by default, enforce server-side, never trust client input for who-am-I.
  2. A02 Cryptographic Failures — data exposed because of weak or missing crypto. Mitigation: TLS everywhere, strong algorithms, no plaintext secrets.
  3. A03 Injection — SQL, NoSQL, OS command, LDAP. Mitigation: parameterized queries, ORMs, input validation, escape output.
  4. A04 Insecure Design — flaws baked into architecture, not just bugs. Mitigation: threat modeling, secure design patterns, defence in depth.
  5. A05 Security Misconfiguration — default credentials, verbose errors, unpatched components, open S3 buckets. Mitigation: hardening baselines, IaC scanning.
  6. A06 Vulnerable and Outdated Components — running libraries with known CVEs. Mitigation: SCA tools (Snyk, Dependabot, Renovate), patch SLAs.
  7. A07 Identification and Authentication Failures — credential stuffing, weak password reset, missing MFA, session fixation.
  8. A08 Software and Data Integrity Failures — trusting unsigned code, insecure deserialization, untrusted CI/CD pipelines. Mitigation: signed artifacts (Sigstore, cosign), SLSA.
  9. A09 Security Logging and Monitoring Failures — you can't respond to what you don't see.
  10. A10 Server-Side Request Forgery (SSRF) — server makes attacker-controlled requests. Mitigation: allow-list outbound destinations, block metadata endpoints (e.g., 169.254.169.254).

SQL Injection — The Canonical Example

Vulnerable code (any language, same shape):

query = f"SELECT * FROM users WHERE email = '{user_input}'"
db.execute(query)

If user_input is ' OR 1=1 --, you just dumped the user table. Fix: use parameterized queries — the database library substitutes parameters safely:

db.execute("SELECT * FROM users WHERE email = %s", (user_input,))

The same idea applies to OS command injection (use subprocess.run([...]) with a list, never shell=True with concatenation), LDAP injection, and template injection. Never glue untrusted input into an interpreter without escaping.

XSS (Cross-Site Scripting)

Attacker injects JavaScript that runs in another user's browser. Three flavours: stored, reflected, DOM-based.

Defences:

  • Contextual output encoding — modern frameworks (React, Vue, Angular) escape by default; only dangerouslySetInnerHTML opts out
  • Content Security Policy (CSP) — HTTP header restricting what scripts can run and from where
  • HttpOnly cookies so JavaScript can't steal sessions
  • Sanitisation libraries (DOMPurify) for cases where you must accept HTML

CSRF

Cross-Site Request Forgery: a malicious site causes the victim's browser to make a state-changing request to a site they're authenticated to. Defences:

  • SameSite cookies (Lax or Strict) — modern browsers default to Lax
  • CSRF tokens validated server-side on every state-changing request
  • Custom request headers (X-Requested-With) for AJAX endpoints — browsers won't send custom headers cross-origin without CORS

API Security

OWASP also publishes an API Top 10. Key practices:

  • Authenticate and authorize every endpoint, not just the gateway
  • Validate input against a schema (OpenAPI / JSON Schema)
  • Rate-limit per token and per IP
  • Avoid BOLA (Broken Object-Level Authorization) — verify the caller owns the requested object on every read
  • Return only the fields the caller needs (no over-exposure of internal data)

Secrets Management

Hardcoded API keys, database passwords, or signing keys in source code or container images are a perennial source of breaches. Treat secrets as a separate concern:

  • Vault tools: HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, Doppler, 1Password
  • Pre-commit scanners: gitleaks, trufflehog, GitHub secret scanning
  • Short-lived credentials via OIDC federation (e.g., GitHub Actions to AWS without static keys)
  • Rotate quickly after any suspected exposure

Securing the SDLC

Don't bolt security on at the end — integrate it at every stage. Tools by category:

ToolWhat it doesExamples
SAST (Static)Analyses source code for vulnerabilities without running itSemgrep, SonarQube, CodeQL, Checkmarx
DAST (Dynamic)Tests a running app from the outside, like an attackerOWASP ZAP, Burp Suite, Nuclei
SCA (Software Composition)Identifies vulnerable open-source dependenciesSnyk, Dependabot, Renovate, Trivy
IAST (Interactive)Instruments running app to find runtime issuesContrast Security
IaC scanningCatches misconfigured Terraform / CloudFormation / K8s manifestsCheckov, tfsec, KICS
Container scanningFinds vulnerable packages in imagesTrivy, Grype, Docker Scout

Run them in CI on every pull request, fail the build on critical findings, and track time-to-remediation as a KPI.

Hardening Headers

A baseline set of security headers every web app should ship:

Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'; ...
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()

Test your site at securityheaders.com or observatory.mozilla.org.

Key Takeaways

  • The OWASP Top 10 is the de-facto checklist for web application risk.
  • Broken access control is consistently the #1 issue — verify authorization on every request, server-side.
  • Injection (SQL, command, LDAP) is solved by parameterized queries and never concatenating user input into queries or commands.
  • Use SAST, DAST, and SCA in CI to catch issues before they reach production.
  • Secrets belong in a vault, never in source code or container images.

Test your knowledge

Try exam-style practice questions to reinforce what you've learned.

Practice Questions →