HTTP Security Headers

Content Security Policy (CSP)

Content Security Policy (CSP) is a powerful security header that acts as a second line of defense against Cross-Site Scripting (XSS), clickjacking, and data injection attacks. By defining a strict CSP, you instruct the browser exactly where it is allowed to load resources from, preventing unauthorized scripts from executing on your site.

The Threat: Cross-Site Scripting (XSS)

XSS occurs when an attacker successfully injects malicious JavaScript into your website (for example, via an unsanitized search input, a blog comment, or a hijacked third-party library). When a user visits the page:

  1. The browser executes the injected script, believing it is legitimate site code.
  2. The malicious script can read session cookies, access localStorage, or hijack user sessions.
  3. The script can exfiltrate this data to an attacker-controlled server.

Even if you sanitize your inputs, a single developer oversight or a compromised npm package can expose your site to XSS.

How CSP Defends Your Site

CSP is an HTTP response header that defines an allowlist of approved sources for scripts, styles, images, and other assets. If an attacker injects a script tag pointing to malicious-domain.com, the browser will inspect the CSP, see that malicious-domain.com is not in the allowlist, and refuse to execute or load the script.

The CSP Header Structure

A basic, secure CSP header looks like this:

Content-Security-Policy: default-src 'self'; script-src 'self' https://trustedscripts.com; img-src 'self' data:; style-src 'self' 'unsafe-inline';

Essential CSP Directives

  • default-src: The fallback directive. If a specific directive (like script-src) is not specified, the browser falls back to this rule. Setting it to 'self' restricts all assets to your own domain by default.
  • script-src: Restricts the locations from which JavaScript can be loaded and executed.
  • style-src: Restricts the sources for stylesheets.
  • img-src: Defines allowed sources for images.
  • connect-src: Restricts the URLs to which scripts can send AJAX requests (using fetch or XHR), WebSockets, or EventSource connections.
  • frame-ancestors: Restricts which domains can embed your site in an <iframe> (modern replacement for the X-Frame-Options header).

Moving Beyond Insecure Fallbacks

Many developers implement a lax CSP to avoid breaking existing site features. However, using the following values renders your CSP largely ineffective:

  • 'unsafe-inline' in script-src: Allows inline <script> tags, rendering your XSS protection void.
  • 'unsafe-eval' in script-src: Allows execution of strings as code (e.g. eval()), which is highly vulnerable.
  • Wildcard domains (* or https:): Allows scripts to be loaded from any server on the internet.

Secure Alternatives: Nonces and Hashes

If you must use inline scripts or styles, avoid 'unsafe-inline'. Instead, use:

  1. Cryptographic Nonces: Generate a unique, random base64 string (the “nonce”) on every page request. Include it in your CSP header and in your inline script tags:
    Content-Security-Policy: script-src 'self' 'nonce-R4nd0mStr1ng';
    <script nonce="R4nd0mStr1ng">
      console.log("This secure inline script runs!");
    </script>
  2. Cryptographic Hashes: Calculate the SHA-256 hash of the exact contents of the inline script and add the hash base64 value directly to the CSP:
    Content-Security-Policy: script-src 'self' 'sha256-qznLgHr1g8/h...';

Deploying CSP Safely: Report-Only Mode

Deploying a strict CSP on a live, complex site can easily break functionalities if a legitimate asset is accidentally blocked. To prevent this, use CSP Report-Only Mode:

Content-Security-Policy-Report-Only: default-src 'self'; report-to /csp-violation-endpoint;

In Report-Only mode, the browser will not block any assets. Instead, it will execute them as normal, but send a detailed JSON report to your specified reporting endpoint whenever a resource violates your policy. This allows you to audit and refine your rules before enforcing them.

Sources & Standards

  • W3C Content Security Policy Level 3 Specification: w3.org/TR/CSP3 - The authoritative specification outlining browser security policies, directives, and injection defense mechanisms.
  • MDN Web Docs: Content Security Policy (CSP) - Comprehensive guides on implementing and troubleshooting CSP headers in web applications.
  • OWASP: Content Security Policy Cheat Sheet - Practical tips for designing secure policies without breaking frontends.
  • Google CSP Evaluator: csp-evaluator.withgoogle.com - A powerful tool developed by Google to visualize and audit your CSP for subtle misconfigurations or bypasses.

How Vioro monitors this

Vioro scans your HTTP headers to verify that a Content-Security-Policy (CSP) is defined. It audits your rules to identify insecure configurations (such as missing directives, wildcards on script sources, or reliance on unsafe-inline) that weaken your XSS defenses.