OWASP Top 10

Backend Fundamentals · Backend Security · 8 min read

1. What problem does this solve?

The OWASP Top 10 is a living list of the most critical web‑application security risks.
It exists because:

  • Security is hard – developers often overlook subtle attack vectors that can be exploited by automated bots or malicious insiders.
  • Commonality – many breaches arise from the same set of weaknesses (e.g., injection, broken auth).
  • Prioritisation – it gives teams a clear, industry‑accepted roadmap for hardening applications.
  • Compliance & risk management – auditors and regulators reference the Top 10 when assessing controls.

If you ignore it, you risk:

  • Data loss or exposure (financial, personal, IP).
  • Regulatory fines (GDPR, PCI‑DSS, HIPAA).
  • Reputation damage and loss of user trust.
  • Legal liability.

In real backends, the Top 10 surfaces in:

  • API endpoints that accept user input (SQL, GraphQL, REST).
  • Authentication flows (JWT, OAuth, session cookies).
  • Data storage (PostgreSQL, MongoDB, Redis).
  • Third‑party libraries (npm packages, Docker images).
  • Deployment pipelines (Docker, Kubernetes, CI/CD).

2. Mental model

Analogy: Think of a web application as a castle.

  • The walls are your input validation and sanitisation.
  • The gatekeepers are authentication and authorization.
  • The keep holds sensitive data; you lock it with encryption.
  • The watchtower is logging/monitoring.

If any wall is weak, a siege (attack) can breach the castle. The OWASP Top 10 tells you which walls are most likely to crumble.

Engineering model:

  • Threat modelling → identify attack surfaces.
  • Risk assessment → map threats to OWASP categories.
  • Mitigation → apply controls (e.g., prepared statements, CSP, rate limiting).
  • Verification → static analysis, dynamic scanning, penetration testing.
  • Monitoring → alerts for anomalous behaviour.

3. Deep explanation

#OWASP CategoryInternalsKey TermsTrade‑offsFailure ModesLimitationsWhere it fitsRelated Concepts
A1InjectionMalformed input reaches a parser (SQL, NoSQL, OS shell).Prepared statements, parameterised queries, escapingPrepared statements reduce flexibility (e.g., dynamic queries).Blind injection, error‑based injection.Some ORMs still allow string interpolation.Data access layer.Input validation, ORM design.
A2Broken AuthenticationCredentials are stored or transmitted insecurely; session fixation.JWT, session cookies, MFA, password hashingStrong hashing (bcrypt) slows login.Credential stuffing, session hijacking.MFA can be bypassed via phishing.Auth service, API gateway.Identity & Access Management (IAM).
A3Sensitive Data ExposureData in transit or at rest is unencrypted or weakly encrypted.TLS, AES‑256, key managementEncryption overhead, key rotation complexity.Man‑in‑the‑middle, key leakage.Legacy protocols (SSLv3).Data storage, API responses.Data‑at‑rest, data‑in‑transit.
A4XML External Entities (XXE)XML parser resolves external entities.Entity resolution, safe‑XML librariesSome XML features disabled; may break integration.Remote code execution, data exfiltration.Not relevant for JSON‑only APIs.XML parsers, legacy services.Secure coding, input sanitisation.
A5Broken Access ControlAuthorization checks are missing or incorrect.Role‑based access control (RBAC), scopesOver‑restrictive scopes can hurt UX.Privilege escalation, data leakage.Mis‑configured ACLs.Business logic layer.IAM, policy engines.
A6Security MisconfigurationDefault configs, open ports, verbose errors.Hardening, least privilege, secrets managementHardening may break dev workflows.Unintended public endpoints.Mis‑configured CI/CD pipelines.Deployment, infrastructure.DevOps, IaC.
A7Cross‑Site Scripting (XSS)Unescaped output rendered in browsers.DOM‑XSS, reflected, storedCSP can reduce functionality.Session hijacking, phishing.Content‑Security‑Policy misconfig.Front‑end rendering.CSP, sanitisation libraries.
A8Insecure DeserializationMalicious payloads are deserialized into objects.Object injection, deserialization librariesStrict type checks reduce flexibility.Remote code execution.Language‑specific quirks.API endpoints, message queues.Serialization, type safety.
A9Using Components with Known VulnerabilitiesThird‑party libs contain CVEs.Dependency‑check, Snyk, npm auditUpgrading may break compatibility.Exploits via package hijacking.Shadowing, lockfile integrity.Build pipeline, runtime.Package management, CI.
A10Insufficient Logging & MonitoringNo audit trail or alerting.Log aggregation, SIEM, anomaly detectionLogging can consume storage, affect performance.Undetected breaches, delayed response.Log tampering, privacy concerns.All layers.Observability, incident response.

4. How it works

Below is a high‑level flow for a secure API request that touches several OWASP categories.

sequenceDiagram
    participant Client
    participant API
    participant Auth
    participant DB
    participant Logger

    Client->>API: HTTPS POST /orders (JWT)
    API->>Auth: Validate JWT
    Auth-->>API: OK
    API->>DB: SELECT * FROM orders WHERE user_id = ?
    DB-->>API: Result
    API->>Client: 200 OK (JSON)
    API->>Logger: Log request & response (mask PII)

Key points:

  1. Transport – TLS (A3).
  2. Auth – JWT verification, MFA (A2).
  3. Input – Parameterised query (A1).
  4. Output – JSON serialisation, CSP headers (A7).
  5. Logging – Mask PII, rotate logs (A10).

5. Practical implementation

Below is a Node.js/TypeScript example that demonstrates mitigations for several OWASP categories in a single endpoint.

// src/routes/orders.ts
import express, { Request, Response } from 'express';
import { verifyJwt } from '../auth/jwt';
import { pool } from '../db';
import { logger } from '../utils/logger';
import { sanitize } from 'dompurify';
import { body, validationResult } from 'express-validator';

const router = express.Router();

/**
 * POST /orders
 *  - Auth: JWT + MFA
 *  - Input: validated & sanitized
 *  - DB: parameterised query
 *  - Output: JSON, CSP headers
 *  - Logging: masked PII
 */
router.post(
  '/',
  // 1️⃣ Validate JWT
  async (req: Request, res: Response, next) => {
    try {
      req.user = await verifyJwt(req.headers.authorization);
      next();
    } catch (e) {
      res.status(401).json({ error: 'Unauthorized' });
    }
  },
  // 2️⃣ Validate & sanitize body
  body('productId').isInt(),
  body('quantity').isInt({ min: 1 }),
  async (req: Request, res: Response) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }

    const { productId, quantity } = req.body;
    const userId = req.user.id;

    try {
      // 3️⃣ Parameterised query (A1)
      const result = await pool.query(
        'INSERT INTO orders (user_id, product_id, quantity) VALUES ($1, $2, $3) RETURNING id',
        [userId, productId, quantity]
      );

      // 4️⃣ Mask PII before logging (A10)
      logger.info('Order created', {
        orderId: result.rows[0].id,
        userId: userId,
        productId,
        quantity,
      });

      // 5️⃣ CSP header (A7)
      res.setHeader(
        'Content-Security-Policy',
        "default-src 'self'; script-src 'none';"
      );

      res.status(201).json({ orderId: result.rows[0].id });
    } catch (err) {
      logger.error('DB error', { error: err.message });
      res.status(500).json({ error: 'Internal server error' });
    }
  }
);

export default router;

Key lines

  • verifyJwt – ensures token integrity (A2).
  • express-validator – sanitises input (A1, A7).
  • pool.query with $1, $2, $3 – prevents SQL injection (A1).
  • CSP header – mitigates XSS (A7).
  • logger.info – masks PII, logs minimal data (A10).

6. Production considerations

ConcernOWASP RelevancePractical Tips
ScalabilityA1, A9Use connection pools, lockfile integrity checks, automated dependency updates.
ReliabilityA6, A10Harden defaults, enable health checks, use circuit breakers.
SecurityAllEnforce TLS 1.2+, rotate keys, use HSTS, enable CSP, use OWASP ZAP or Snyk.
ObservabilityA10Centralised logs (ELK), distributed tracing, anomaly detection.
PerformanceA1, A3Cache encrypted data in Redis, use prepared statements, avoid heavy sanitisation on every request.
Error handlingA10Return generic error messages, log stack traces separately.
Resource usageA9Pin dependencies, audit for unused packages, use lightweight libs.
Operational concernsA6Immutable infrastructure, secrets in Vault/K8s secrets, CI/CD pipelines with automated scans.
Failure recoveryA5, A10Role‑based backups, audit trails, incident response playbooks.
DeploymentA6, A9Use Docker images signed with Notary, run npm audit in CI, enforce policy checks.

7. Common mistakes

MistakeWhy it’s bad
String concatenation for SQLEnables injection (A1).
Storing passwords in plain textData breach, regulatory non‑compliance (A3).
Ignoring CSPXSS attacks succeed (A7).
Using default config filesOpen ports, verbose errors (A6).
Hard‑coding secretsSecrets leak via source control (A6).
Skipping dependency auditVulnerable libs (A9).
Logging raw request bodiesPII exposure (A10).
Assuming JWT is enoughNo MFA, session fixation (A2).
Not rotating encryption keysLong‑term data exposure (A3).
Over‑restrictive rate limitsDenial‑of‑service for legitimate users.

8. Senior engineer perspective

What changes at scale?

  • Distributed auth – use a centralised identity provider (OAuth2/OIDC) instead of per‑service JWTs.
  • Policy engine – externalise RBAC to a service like OPA or Keycloak.
  • Zero‑trust networking – enforce mutual TLS between services.
  • Observability stack – ingest logs into a SIEM, correlate with network telemetry.
  • Automated compliance – policy‑as‑code, continuous security scanning in CI/CD.

Design decisions

DecisionTrade‑offsBottlenecksMonitoring
Centralised authSingle point of failure, but simplifies revocation.Auth service latency.Auth request latency, token revocation rate.
Encrypted DB columnsPerformance hit, key rotation complexity.Query performance on encrypted columns.Encryption key access latency.
CSP with strict policyMay break third‑party widgets.Front‑end compatibility.CSP violation reports.
Immutable containersFaster rollbacks, but requires robust CI.Build time, storage.Image scan results.
Rate limiting per IPDDoS protection, but may block legitimate users behind NAT.Cache size for counters.Rate‑limit hit metrics.

When NOT to use an approach

  • JWT without rotation – if you need to revoke tokens quickly.
  • Hard‑coded secrets – in any environment that is not fully isolated.
  • No logging – if you need to meet compliance or forensic requirements.
  • No dependency audit – in production systems with external exposure.

9. Interview questions

#QuestionAnswer Points
1 (beginner)What is SQL injection and how can you prevent it?• Malicious SQL in user input.
• Use parameterised queries / prepared statements.
• Avoid string concatenation.
2 (beginner)Why is TLS important for a web API?• Encrypts data in transit.
• Protects against MITM.
• Enables HSTS, secure cookies.
3 (senior)How would you design a scalable authentication system for microservices?• Centralised IdP (OAuth2/OIDC).
• Token introspection or short‑lived JWTs.
• MFA, device trust.
• Revocation strategy.
4 (senior)Explain how you would implement zero‑trust networking in a Kubernetes cluster.• Mutual TLS between pods.
• Service mesh (Istio/Linkerd).
• Fine‑grained mTLS policies.
• Certificate rotation.
5 (scenario/debugging)A production API is returning 500 errors after a recent deployment. The logs show Error: Invalid input from the database driver. What could be happening?• Possible injection due to missing parameterisation.
• Schema change (column renamed).
• Data type mismatch.
• Fix: review query, validate schema, add unit tests.

10. Hands‑on task

Add an OWASP‑compliant rate‑limiting middleware to the existing Express app.

  1. Install express-rate-limit.
  2. Configure a per‑IP limit of 100 requests per 15 min.
  3. Store counters in Redis for horizontal scaling.
  4. Log each rate‑limit hit with IP and endpoint.
  5. Write a test that simulates 101 requests and asserts a 429 response.

11. Quick revision

  • OWASP Top 10 = 10 most critical web‑app risks.
  • A1 Injection – use prepared statements.
  • A2 Broken Auth – MFA, secure JWTs, session rotation.
  • A3 Sensitive Data – TLS, AES‑256, key rotation.
  • A4 XXE – disable external entity resolution.
  • A5 Broken Access – RBAC, scopes, policy engine.
  • A6 Misconfiguration – harden defaults, secrets in Vault.
  • A7 XSS – CSP, output escaping, DOM sanitisation.
  • A8 Insecure Deserialization – strict type checks, safe libs.
  • A9 Known Vulnerabilities – dependency audit, lockfiles.
  • A10 Logging – mask PII, rotate logs, SIEM integration.
  • Use parameterised queries to stop injection.
  • CSP + XSS‑filter = front‑end hardening.
  • JWT + MFA = strong auth.
  • Redis for distributed rate‑limiting.
  • Snyk / npm audit for component checks.
  • Centralised logging (ELK) for monitoring.

12. References