SECURITY 13 min

OWASP Top 10 Web & APIs: XSS, CSRF, SQLi & HTTP Headers

A technical analysis of the most critical web vulnerabilities. Defensive strategies to secure modern applications: input sanitization, strict CORS headers, and CSRF protection.

Written by Samir El Azem Crovetto • Senior Backend Engineer & DevSecOps

The Enterprise Web and API Threat Landscape

Modern web applications and distributed RESTful APIs represent an organization's primary public digital interface, and consequently, its most targeted attack surface. Despite advancements in contemporary frameworks, runtimes, and compiler toolchains, foundational vulnerability classes from the OWASP Top 10 and OWASP API Security Top 10 continue to dominate corporate breach and incident response reports.

The persistence of these vulnerability vectors is rarely caused by the absence of cryptographic algorithms or perimeter firewalls; it stems from systemic failures in untrusted input sanitization, unjustified implicit trust in client browsers, and the omission of defensive HTTP security headers at server and reverse proxy layers.

Neutralizing these attack vectors systematically requires an architectural Defense-in-Depth strategy: coupling strictly typed, parameterized data persistence on the backend with browser-enforced execution containment via modern HTTP security headers.


Defense-in-Depth Architecture: Request Inspection and Perimeter Flow

The communication path between a user's web browser and backend application services must enforce multiple inspection boundaries before modifying application state:

graph TD
    subgraph Browser_Client ["🌐 Client Browser"]
        User["User / Adversary"]
        DOM["DOM Tree & JS Execution Context"]
        CSP_Engine["CSP & Security Header Enforcement Engine"]
    end

    subgraph Edge_Gateway ["🛡️ Perimeter Gateway (Reverse Proxy / WAF)"]
        WAF["WAF: SQLi / XSS Inspection"]
        HeaderInjector["HTTP Security Header Injection:<br/>HSTS, CSP, Frame-Ancestors, Permissions-Policy"]
    end

    subgraph Backend_Application ["⚙️ Backend Application (Spring Boot / Node.js)"]
        CSRF_Filter["Anti-CSRF Filter (SameSite + Double Submit Token)"]
        InputValidator["Strict Schema & Type Validator"]
        ORM_DAL["Persistence Tier (Parameterized Prepared Statements)"]
        Database[("Relational SQL Database")]
    end

    User -->|HTTP Request with Payload| WAF
    WAF -->|Sanitized Ingress| CSRF_Filter
    WAF -.->|Malicious Payload Intercepted| Block["HTTP 403 Forbidden"]
    CSRF_Filter --> InputValidator
    InputValidator --> ORM_DAL
    ORM_DAL -->|Parameterized Query Execution| Database
    Database --> ORM_DAL
    ORM_DAL --> HeaderInjector
    HeaderInjector -->|Response with Hardened Headers| CSP_Engine
    CSP_Engine --> DOM

    classDef client fill:#e1f5fe,stroke:#0288d1,stroke-width:2px;
    classDef edge fill:#fff3e0,stroke:#f57c00,stroke-width:2px;
    classDef backend fill:#e8f5e9,stroke:#388e3c,stroke-width:2px;
    classDef block fill:#ffebee,stroke:#d32f2f,stroke-width:2px;

    class User,DOM,CSP_Engine client;
    class WAF,HeaderInjector edge;
    class CSRF_Filter,InputValidator,ORM_DAL,Database backend;
    class Block block;

1. SQL Injection (SQLi): Parameterization and ORM Pitfalls

SQL Injection occurs when untrusted user input is concatenated directly into SQL command strings, altering the query structure executed by the database engine.

The Vulnerable Concatenation Antipattern:

// Vulnerable: Direct string concatenation of untrusted input
String query = "SELECT * FROM users WHERE username = '" + userInput + "' AND password = '" + password + "'";
Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery(query);

Supplying admin' -- evaluates the expression to true and truncates the password check, granting unauthorized administrative access.

The Mathematical Remediation: Parameterized Prepared Statements

In parameterized queries, the database engine compiles the query's Abstract Syntax Tree (AST) before binding argument values. User input is treated strictly as literal data, preventing input characters from functioning as syntactic command delimiters:

// Secure: Type-safe bound parameters at runtime
String safeQuery = "SELECT id, username, email FROM users WHERE username = ? AND is_active = ?";
try (PreparedStatement pstmt = connection.prepareStatement(safeQuery)) {
    pstmt.setString(1, userInput);
    pstmt.setBoolean(2, true);
    try (ResultSet rs = pstmt.executeQuery()) {
        // Safely process query result set
    }
}

Hidden Vulnerabilities in ORMs and Modern Data Frameworks:

A common misconception is assuming that using an ORM like Hibernate or Spring Data JPA automatically immunizes an application against SQLi. As detailed in our Spring Data JPA production guide, severe vulnerabilities frequently arise in real-world codebases:

  • String concatenation inside JPQL/HQL queries (entityManager.createQuery("FROM Account WHERE iban = '" + iban + "'")).
  • Concatenating clauses when constructing dynamic queries with the CriteriaBuilder API.
  • Using native SQL queries (@Query(value = "...", nativeQuery = true)) without named bind variables (:paramName).

2. Cross-Site Scripting (XSS): Context-Aware Encoding & Content Security Policy (CSP)

Cross-Site Scripting allows attackers to execute malicious JavaScript within the browser context of a legitimate user, enabling session hijacking, credential theft, and unauthorized DOM manipulation.

Taxonomy of XSS Attacks:

  1. Reflected XSS: The attack payload is delivered via HTTP request parameters (e.g., in a URL search parameter ?q=<script>...) and reflected immediately in the server's HTML response without sanitization.
  2. Stored XSS: The malicious payload is persistently written to backend data storage (comments, profile names, support tickets) and delivered to all subsequent users viewing that record.
  3. DOM-based XSS: The vulnerability exists entirely within client-side JavaScript execution, where dangerous sinks (innerHTML, document.write, eval) consume untrusted sources (location.hash, window.name).

Context-Aware Output Encoding:

Simple character replacement is insufficient. Encoding algorithms must align with the exact structural DOM insertion context:

Insertion Context Hazardous Characters Mandatory Mitigation Standard
HTML Body (<div>...</div>) & < > " ' / HTML entity encoding (&lt;, &gt;, &quot;)
HTML Attribute (<input value="...">) Non-alphanumeric characters Hex attribute encoding (&#xHH;)
JavaScript Block (<script>var x = ...</script>) Escape characters \, ", ', < Strict JSON serialization (JSON.stringify)
URL Parameter (<a href="/search?q=...">) Whitespace, URL query delimiters Strict percent encoding (encodeURIComponent)

The Definitive Defense: Cryptographic Nonce-Based Content Security Policy (CSP)

Content Security Policy (CSP) is an HTTP response header that restricts the origins and signatures from which browsers are permitted to load and execute scripts, styles, and media.

The modern standard abandons domain allowlists (which are routinely bypassed via shared CDN endpoints) in favor of Cryptographic Nonces:

Content-Security-Policy: 
  default-src 'none';
  script-src 'nonce-dGhpcyBpcyBhIHJhbmRvbSBub25jZQ==' 'strict-dynamic' https: 'unsafe-inline';
  style-src 'self' 'nonce-dGhpcyBpcyBhIHJhbmRvbSBub25jZQ==';
  img-src 'self' data: https:;
  font-src 'self';
  connect-src 'self' https://api.enterprise.local;
  base-uri 'none';
  form-action 'self';
  frame-ancestors 'none';
  • Every authorized inline script must carry a nonce="dGhpcy..." attribute, randomly generated per HTTP request by the server.
  • Any unauthorized script injected by an attacker will lack the valid session nonce and will be immediately blocked by the browser engine, neutralizing execution.

3. Cross-Site Request Forgery (CSRF): SameSite Cookies & Double Submit Tokens

CSRF exploits the browser's automatic inclusion of stored session credentials when issuing cross-origin requests. An adversary tricks an authenticated user into visiting a malicious website that issues background POST requests against corporate applications, triggering state-changing operations without consent.

Mitigation Strategy 1: The SameSite Cookie Attribute

Modern HTTP cookie specifications prevent unintended ambient credential transmission:

Set-Cookie: JSESSIONID=abc123xyz789; Path=/; Secure; HttpOnly; SameSite=Strict
  • SameSite=Strict: The cookie is never sent across third-party site requests, even during inbound top-level link navigations. Ideal for sensitive administration consoles and financial portals.
  • SameSite=Lax: Cookies are withheld on cross-site sub-resource requests (POST/PUT/images), but sent on top-level safe GET navigations.

Mitigation Strategy 2: Double Submit Cookie Pattern for Stateless REST APIs

For decoupled Single Page Applications (SPAs) and stateless REST services, utilize the Double Submit Cookie pattern:

  1. The server generates a cryptographically random token sent as a readable cookie (XSRF-TOKEN).
  2. On every state-changing request (POST, PUT, DELETE), frontend clients copy the cookie value into a custom request header (X-XSRF-TOKEN).
  3. The backend validates that the header matches the cookie value. Due to the Same-Origin Policy (SOP), malicious third-party origins cannot read the cookie or forge the custom header.

4. Clickjacking and UI Redressing: From X-Frame-Options to frame-ancestors

Clickjacking involves embedding an authorized application within a transparent <iframe> overlaid over an enticing decoy website. When users click on decoy buttons, they inadvertently trigger actions within the hidden application (such as "Authorize Access" or "Confirm Payment").

Legacy Header: X-Frame-Options

Historically, developers implemented:

X-Frame-Options: DENY
# or
X-Frame-Options: SAMEORIGIN

However, X-Frame-Options cannot support granular domain allowlists and is not standardized within W3C specifications.

Modern Standard: The CSP frame-ancestors Directive

The frame-ancestors directive within Content Security Policy replaces and supersedes X-Frame-Options:

# Disallow framing by any origin
Content-Security-Policy: frame-ancestors 'none';

# Permit framing exclusively by the same origin
Content-Security-Policy: frame-ancestors 'self';

# Permit framing only by an authorized corporate portal
Content-Security-Policy: frame-ancestors 'self' https://portal.enterprise.local;

Browsers encountering frame-ancestors will reject nested iframe rendering from unauthorized parent origins, neutralizing UI redressing attacks.


5. Production HTTP Security Headers Baseline

To establish a resilient security posture, every web server, API Gateway, and reverse proxy should inject this baseline across all HTTP responses:

# Recommended configuration for Nginx / Envoy / Express
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always;
add_header X-Frame-Options "DENY" always; # Fallback for legacy clients
  • Strict-Transport-Security (HSTS): Mandates HTTPS connections for 2 years (max-age=63072000), mitigating SSL stripping attacks.
  • X-Content-Type-Options: nosniff: Prevents MIME type sniffing, ensuring browsers treat assets strictly according to declared Content-Type headers.
  • Permissions-Policy: Disables access to sensitive device APIs (camera, microphone, geolocation) for third-party scripts and iframes.

Enterprise Web & API Security Checklist

  • [x] All database queries execute via parameterized Prepared Statements, preventing ORM injection leaks.
  • [x] Context-aware output encoding enforced across all dynamic HTML, attribute, and JavaScript insertions.
  • [x] Nonce-based Content Security Policy (CSP) deployed with the frame-ancestors directive.
  • [x] Session and authentication cookies protected with HttpOnly, Secure, and SameSite attributes.
  • [x] Stateless REST mutation endpoints protected via Double Submit CSRF token validation.
  • [x] Comprehensive HTTP security header baseline (HSTS with preload, nosniff, Permissions-Policy) enforced at the perimeter.

If you need to audit your organization's web application and API security, implement advanced CSP policies, or remediate OWASP Top 10 vulnerabilities across your technology stack, explore my Cybersecurity Consulting Services or reach out directly via About Me.