Safety

OWASP Top 10

The ten most critical web application security risks, updated regularly by the open community.

Overview

The OWASP (Open Web Application Security Project) Top 10 is the most widely referenced security standard for web applications. Published every 3-4 years, it categorises the most critical security risks. The 2021 edition lists: A01 Broken Access Control, A02 Cryptographic Failures, A03 Injection, A04 Insecure Design, A05 Security Misconfiguration, A06 Vulnerable Components, A07 Authentication Failures, A08 Software Integrity Failures, A09 Logging Failures, A10 SSRF.

Origin

OWASP was founded in 2001. The first Top 10 was published in 2003. It has been revised in 2004, 2007, 2010, 2013, 2017, and 2021. The Top 10 is referenced in PCI DSS, HIPAA technical safeguards, and NIST SP 800-53. OWASP also publishes the Application Security Verification Standard (ASVS) as a more comprehensive control catalogue.

Examples

SSRF (A10) prevention in TypeScript

import { URL } from 'url';
import { isIP } from 'net';
import fetch from 'node-fetch';

const PRIVATE_RANGES = [
  /^10.d+.d+.d+$/,
  /^172.(1[6-9]|2d|3[01]).d+.d+$/,
  /^192.168.d+.d+$/,
  /^127.d+.d+.d+$/,
  /^169.254.d+.d+$/,
  /^::1$/,
];

function isPrivateIP(ip: string): boolean {
  return PRIVATE_RANGES.some(r => r.test(ip));
}

async function safeFetch(userProvidedUrl: string): Promise<Response> {
  let parsed: URL;
  try {
    parsed = new URL(userProvidedUrl);
  } catch {
    throw new Error('Invalid URL');
  }

  if (!['http:', 'https:'].includes(parsed.protocol)) {
    throw new Error('Only http and https protocols are allowed');
  }

  const ip = isIP(parsed.hostname) ? parsed.hostname : null;
  if (ip && isPrivateIP(ip)) {
    throw new Error('Requests to private IP addresses are not allowed');
  }

  if (parsed.hostname === 'localhost' || parsed.hostname.endsWith('.internal')) {
    throw new Error('Requests to internal hostnames are not allowed');
  }

  return fetch(userProvidedUrl, { redirect: 'error' });
}

redirect: "error" prevents SSRF via redirect chains where the initial URL is public but redirects to an internal address. DNS rebinding bypasses hostname checks; a complete SSRF defence requires resolving the hostname and checking the IP at request time, not just the URL string.

Broken Access Control (A01) with row-level authorisation in Ruby

class OrdersController < ApplicationController
  before_action :set_order, only: %i[show update destroy]

  def show = render json: @order
  def update
    @order.update!(order_params)
    render json: @order
  end

  private

  # WRONG: fetches by ID only, no ownership check
  def set_order_wrong
    @order = Order.find(params[:id])
  end

  # CORRECT: scope to current user, raise 404 for orders belonging to others
  # An attacker cannot determine whether an order exists or belongs to another user
  def set_order
    @order = current_user.orders.find(params[:id])
    # Rails raises ActiveRecord::RecordNotFound if not found, which renders 404
  end

  def order_params
    params.require(:order).permit(:shipping_address_id, :coupon_code)
  end
end

Scoping every lookup to current_user.orders prevents IDOR (Insecure Direct Object Reference). An attacker incrementing the order ID receives 404, not data belonging to another user. Strong parameter permit lists prevent mass assignment of status or total_cents.

Use Cases

  • 01Security training: the OWASP Top 10 is the standard curriculum for introducing developers to web security
  • 02Threat modelling sessions where the Top 10 categories serve as a checklist for identifying attack surfaces
  • 03Code review checklists aligned to Top 10 categories for each type of change (authentication changes, data handling, external integrations)
  • 04Penetration testing scope definition: Top 10 categories map to specific test cases that can be systematically verified

When Not to Use

  • //Do not treat the Top 10 as a complete security standard; it is a awareness document, not a comprehensive control framework. Use ASVS Level 2 or 3 for comprehensive coverage
  • //Do not check Top 10 compliance only at launch; vulnerabilities can be introduced in any sprint and should be checked continuously
  • //Do not apply OWASP web application controls to non-web attack surfaces (mobile, desktop, firmware) without adapting them to the relevant threat model

Technical Notes

  • OWASP ASVS (Application Security Verification Standard, v4.0) has 286 controls across 14 categories at three levels: Level 1 (all apps), Level 2 (most apps), Level 3 (highest security applications). It is significantly more comprehensive than the Top 10
  • The shift from A3 (Injection) in 2017 to A3 (Injection, including XSS) in 2021 reflects the consolidation of related vulnerability classes. A10:2021 SSRF is new, reflecting the proliferation of cloud metadata endpoints
  • OWASP Web Security Testing Guide (WSTG v4.2) provides test cases for each Top 10 category with specific HTTP payloads and manual verification steps
  • CWE (Common Weakness Enumeration, MITRE) is the underlying taxonomy that OWASP categories map to; each Top 10 entry lists associated CWE IDs for programmatic tooling integration