SecureBlockLog inStart a pentest
Vulnerability Repository
MediumMisconfiguration

Missing Security Headers

Absent or misconfigured HTTP security headers leave browsers without critical protections against XSS, clickjacking, MIME sniffing, and cross-origin data leakage.

CVSS 5.3CWE CWE-693OWASP A05:2021 — Security Misconfiguration

Description

Missing security headers (CWE-693 — Protection Mechanism Failure) refers to the absence or misconfiguration of HTTP response headers that instruct browsers to enforce additional security policies on the loaded content. Modern browsers implement a rich set of opt-in security features — content security policies, clickjacking protections, MIME type enforcement, cross-origin isolation, and transport security enforcement — all of which are disabled by default and must be explicitly enabled by the server. When these headers are absent, browsers operate in a permissive legacy compatibility mode that increases the attack surface for client-side vulnerabilities.

Under OWASP A05:2021 — Security Misconfiguration, missing security headers represent a failure to enable available platform protections. Individually, each missing header has a specific risk. Collectively, their absence creates a layered reduction in the browser's defensive posture. Some headers (like HSTS and CSP) have significant standalone impact; others (like X-Frame-Options) mitigate specific attacks that could otherwise be critical.

Security headers are a low-effort, high-value control. They require server-side configuration changes rather than code changes and can often be added in a single deployment. Despite this, they are routinely absent or misconfigured in production applications discovered during penetration testing.

How It Works

Each missing security header creates a distinct exposure:

Content-Security-Policy (CSP) absent or set to unsafe-inline: Without CSP, the browser executes any inline script and loads resources from any origin. A successful XSS attack can load external malware, steal cookies, and exfiltrate data without restriction. A restrictive CSP limits what XSS payloads can do:

# Missing or weak CSP:
Content-Security-Policy: default-src *; script-src * 'unsafe-inline' 'unsafe-eval'

# Strong CSP:
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; object-src 'none'; frame-ancestors 'none'

X-Frame-Options / frame-ancestors absent: Without this header, the application can be embedded in an <iframe> on any origin. An attacker creates a transparent overlay on their site, tricking victims into clicking UI elements they cannot see — a clickjacking attack. For example, a transparent iframe over a "Transfer Funds" button causes the victim to unknowingly authorize a bank transfer.

Strict-Transport-Security (HSTS) absent: Without HSTS, a first-visit user connecting over HTTP is vulnerable to SSLStrip, where an attacker downgrades the connection to HTTP and intercepts credentials.

X-Content-Type-Options: nosniff absent: Without this header, Internet Explorer and some Chrome configurations perform MIME sniffing — inferring the content type from the response body rather than the declared Content-Type. An attacker who uploads a text file containing JavaScript code can cause the browser to execute it as a script if the server does not specify nosniff.

Permissions-Policy absent: Without explicit opt-out, scripts on the page (including third-party scripts from ad networks and analytics) can access sensitive browser APIs: camera, microphone, geolocation, payment, and USB. Restricting these via Permissions-Policy reduces the damage radius of any XSS or supply chain compromise.

Referrer-Policy absent or set to unsafe-url: Sensitive URL fragments (tokens in query strings, internal paths) may be included in the Referer header sent to third-party resources, leaking internal URLs or session tokens to analytics and CDN providers.

Impact

  • XSS amplification — absent CSP means any XSS payload has full browser capabilities: cookie access, external requests, DOM manipulation, and credential harvesting.
  • Clickjacking — absent X-Frame-Options allows UI redressing attacks that trick users into performing unintended actions.
  • MIME confusion attacks — absent X-Content-Type-Options enables content sniffing attacks that execute uploaded files as scripts.
  • HSTS bypass — absent HSTS allows first-visit downgrade attacks to HTTP where credentials are intercepted.
  • Sensitive URL leakage — absent Referrer-Policy leaks internal URLs and query string tokens to third-party analytics providers.
  • Permission API abuse — absent Permissions-Policy allows third-party scripts to request access to camera, microphone, and location APIs.

Detection

  1. Scan with automated header analysis tools — run securityheaders.com (online), Mozilla Observatory (observatory <host>), or nikto against the target application. These tools report all missing and misconfigured headers with severity ratings.
  2. Inspect raw HTTP responses with Burp Suite or browser DevTools — check the Response Headers tab for the presence of each security header.
  3. Test clickjacking — embed the target in an <iframe> on a test page. If the page loads in the iframe, X-Frame-Options or frame-ancestors is missing.
  4. Evaluate CSP strictness — if CSP is present, use CSP Evaluator (csp-evaluator.withgoogle.com) to identify weaknesses: unsafe-inline, unsafe-eval, wildcard sources, or missing directives.
  5. Verify HSTS — check for Strict-Transport-Security in HTTPS responses. Confirm max-age is at least 31,536,000 (1 year) and that includeSubDomains is present.
  6. Check API endpoints independently — API responses often have different (or absent) security headers compared to the main web application. Test both the HTML-serving and API-serving endpoints.

Remediation

Configure the following headers on all responses. In nginx:

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Frame-Options "DENY" 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 Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; object-src 'none'; frame-ancestors 'none'" always;

CSP deployment process: Start with Content-Security-Policy-Report-Only pointed to a reporting endpoint. Collect violations for 1-2 weeks, adjust the policy to allow legitimate sources, then switch to enforcing mode.

Cross-Origin headers for isolation: For applications that do not require cross-origin resource sharing, add Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp to enable full cross-origin isolation, which unlocks SharedArrayBuffer while preventing cross-origin data leakage.

Use a security header middleware library. Frameworks like Helmet.js (Node.js), django-csp (Python), and SecurityHeaders (ASP.NET) apply all headers with secure defaults in a single middleware addition.

Ready when you are
Scope a pentest in the next two minutes.
Start scoping