← Back to Articles
Web Security • CSP Hardening

Implementing Strict Content Security Policy (CSP) & Security Headers

Implementing Strict Content Security Policy (CSP) & Security Headers
Defense-in-Depth Web Application Hardening with HTTP Security Headers
Executive Summary & Key Security Takeaways
  • XSS Mitigation:Content Security Policy (CSP) stops Cross-Site Scripting by restricting script execution to cryptographically nonced or hashed scripts.
  • Clickjacking Defense:X-Frame-Options: DENYandframe-ancestors 'none'prevent malicious iframe embedding.
  • Strict Transport Security:Enforce HTTPS and HSTS preloading withmax-age=63072000; includeSubDomains; preload.
  • MIME Sniffing Defense:X-Content-Type-Options: nosniffprevents browsers from misinterpreting non-executable files as executable scripts.

1. Understanding Content Security Policy (CSP)

CSP is an HTTP response header that defines an explicit allowlist of trusted resource origins. Without a CSP, browsers execute any JavaScript present in the HTML document, including malicious payloads injected via DOM manipulation or reflected parameters. With a strict CSP, the browser enforces execution rules before running script blocks or executing dynamic fetches.

2. Defense-in-Depth: Why Input Sanitization Alone Is Insufficient

While input sanitization (using tools like DOMPurify) and output encoding are essential first lines of defense, complex modern web applications with client-side templating frameworks frequently suffer from edge-case vulnerabilities:

A strict Content Security Policy acts as an independent safety net: even if an attacker successfully injects a <script src="https://evil.com/payload.js"> payload into the DOM, the browser refuses to fetch or execute the file because evil.com is not explicitly nonced or trusted.

3. Strict CSP Directives: Nonce-Based & Hash-Based Execution

Legacy CSP configurations relied on domain allowlists (e.g., script-src 'self' https://trustedcdn.com). However, security research demonstrates that domain allowlists can often be bypassed via JSONP endpoints or open redirects on whitelisted domains.

Modern security standards mandate a Strict Nonce-Based CSP or Strict Hash-Based CSP:

Key directives breakdown:

# Recommended Strict Nonce-Based Content Security Policy Header
Content-Security-Policy: default-src 'none'; script-src 'nonce-rAnd0mN0nc3vAlu3' 'strict-dynamic'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self' https://api.zyekh.com https://chat.zyekh.com https://api.zyekh.com https://chat.zyekh.com; frame-ancestors 'none'; base-uri 'none'; form-action 'self'; upgrade-insecure-requests;

3. Configuring Nginx & Apache Security Headers

To achieve maximum HTTP security ratings (A+ rating on SSL Labs and SecurityHeaders.com), configure Nginx to deliver a comprehensive suite of security headers:

# /etc/nginx/conf.d/security-headers.conf

# Content Security Policy (Strict Nonce/Self Baseline)
add_header Content-Security-Policy "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self' https://api.zyekh.com https://chat.zyekh.com https://api.zyekh.com https://chat.zyekh.com; frame-ancestors 'none'; base-uri 'none'; form-action 'self'; upgrade-insecure-requests;" always;

# HTTP Strict Transport Security (HSTS 2 Years + Preload)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

# Prevent MIME-Sniffing Exploits
add_header X-Content-Type-Options "nosniff" always;

# Frame Options (Anti-Clickjacking)
add_header X-Frame-Options "DENY" always;

# Referrer Policy (Protect User Privacy)
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# Permissions Policy (Disable Unused Web APIs)
add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=()" always;

4. Trusted Types & Subresource Integrity (SRI)

Modern web applications handling user-generated input can enforce Trusted Types via the require-trusted-types-for 'script' directive. Trusted Types prevents DOM-based XSS by requiring string inputs passed to dangerous sink functions (such as innerHTML, document.write, or eval) to be wrapped in a sanitizing TrustedHTML policy object.

Combine Trusted Types with Subresource Integrity (SRI) hashes on external CDN scripts to guarantee that third-party library files have not been modified or compromised in transit:


5. Automated CSP Violation Reporting (Report-To)

Deploying CSP in Content-Security-Policy-Report-Only mode allows you to monitor potential policy breaches without blocking legitimate scripts during testing:

Content-Security-Policy-Report-Only: default-src 'none'; script-src 'self'; report-uri /api/csp-report;

5. Security Headers Comparison Matrix

Summary of mandatory HTTP security headers and their defense focus:

Frequently Asked Questions (FAQ)

What is Content Security Policy (CSP) and how does it prevent XSS?

Content Security Policy (CSP) is an HTTP header that allows site operators to restrict the resources (such as JavaScript, CSS, Images) that the browser is allowed to load for a given page, blocking injected Cross-Site Scripting (XSS) scripts.

What is the difference between CSP Nonce and CSP Hash?

A CSP Nonce is a cryptographically strong, single-use random string generated on every request for inline scripts. A CSP Hash is a cryptographic SHA-256 hash of a static inline script content.

Zyekh Abdul Qadir Jailani

Written by Zyekh Abdul Qadir Jailani

Digital Forensics & Incident Response (DFIR) Specialist & Security Researcher specializing in Linux kernel hardening, threat hunting, and system security research.

Utility Security Tools Related to this Article:

Gunakan Generate CSP Hashes -> untuk membantu alur kerja konfigurasi keamanan Anda secara privasi di browser.