Web Development

Content Security Policy (CSP): Definition & Directives

Define and implement Content Security Policy (CSP) to block XSS and clickjacking. Directives, nonces, and strict CSP help protect site user data.

18.1k
content security policy
Monthly Search Volume

Entity Tracking

  • Content Security Policy (CSP): A series of instructions sent from a website to a browser that restricts the sources of code and content the browser is allowed to load.
  • Cross-Site Scripting (XSS): A security vulnerability where an attacker executes malicious code within the context of a trusted website.
  • Directives: Individual instructions within a CSP, such as script-src or img-src, that control specific categories of resources.
  • Nonce: A unique, random "number used once" that a server generates for every HTTP response to validate trusted scripts.
  • Fetch Directives: CSP commands that specify which locations are trusted for loading resources like JavaScript, CSS, or images.
  • Strict CSP: A security strategy that uses nonces or hashes rather than host allowlists to prevent unauthorized script execution.
  • Clickjacking: An attack where a user is tricked into clicking a hidden or disguised element on a website.
  • Injection Sinks: Web platform APIs, such as eval() or innerHTML, that can interpret string input as executable code.

Content Security Policy (CSP) is a security standard that restricts the types of content a browser can load for a specific website. It acts as a safety layer that helps prevent common attacks like cross-site scripting (XSS) and clickjacking. By implementing a CSP, you protect your site’s reputation and user data from malicious code injection.

What is Content Security Policy (CSP)?

A CSP consists of a set of rules, known as directives, sent by a web server to a browser. These rules tell the browser exactly which sources of scripts, styles, and images are trusted. If an attacker tries to inject code from an unauthorized source, the browser will block it.

This standard is widely supported by modern browsers. The [Level 3 draft is currently being developed and adopted as of 2023] (W3C). While primarily a technical security tool, it is essential for SEO and marketing practitioners to understand because it prevents site defacement and unauthorized redirects that can damage search rankings.

Why Content Security Policy (CSP) matters

  • Blocks XSS attacks. It stops malicious scripts from accessing local storage or impersonating users even if your input sanitization fails.
  • Prevents Clickjacking. Directives like frame-ancestors stop other sites from embedding your content in invisible frames to steal clicks.
  • Reduces site defacement. By controlling what can be rendered, it prevents attackers from changing your site’s appearance.
  • Improves mobile security. It manages resource loading across different devices to ensure third-party tools do not introduce vulnerabilities.
  • Enables HTTPS migration. It can automatically upgrade insecure resource requests to the secure HTTPS protocol.

How Content Security Policy (CSP) works

CSP is typically delivered to the browser as an HTTP response header named Content-Security-Policy. For example, a basic policy might look like this:

Content-Security-Policy: default-src 'self'; img-src 'self' trusted-images.com

This instruction tells the browser to: 1. Load all resources by default only from the site's own origin. 2. Allow images from the site's own origin and a specific external domain.

Directives are separated by semicolons. If a browser encounters a resource not listed in these directives, it blocks the load and can send a report to a specified URL. Developers use this reporting to find and fix policy violations without breaking the site for users.

Types of Content Security Policy (CSP)

Allowlist CSP

This traditional method lists specific domain names that are permitted to load resources. While common, this approach is often difficult to maintain. For instance, [just to integrate Google Analytics, a developer is asked to add 187 Google domains to the allowlist] (Netlify).

Strict CSP

Current best practices favor a Strict CSP. Instead of listing every domain name, it uses nonces or hashes. Research indicates that [allowlist CSPs often fail to provide effective protection against XSS due to insecure allowlists] (ACM Digital Library). Strict CSPs are easier to maintain because you only need to mark your own scripts as trusted.

Best practices

  • Avoid 'unsafe-inline'. This keyword allows inline scripts, which are the most common way hackers exploit XSS vulnerabilities.
  • Use the 'report-only' mode during setup. Use the Content-Security-Policy-Report-Only header to see what would be blocked without actually stopping any content.
  • Apply 'frame-ancestors none'. Unless your site needs to be embedded in an iframe, set this to prevent clickjacking.
  • Implement 'strict-dynamic'. This allows a trusted script to load additional dependencies automatically, simplifying your policy.
  • Sanitize input. CSP is a second line of defense. Always sanitize user input as your primary security measure.

Common mistakes

Mistake: Relying on the <meta> tag for all protections. Fix: Use HTTP headers whenever possible. The meta tag does not support framing protections or violation logging.

Mistake: Using X-Content-Security-Policy or X-WebKit-CSP. Fix: These headers are deprecated and buggy. Use the standard Content-Security-Policy header.

Mistake: Combining 'none' with other values. Fix: The 'none' keyword must stand alone. If you add other sources next to it, the browser may ignore the entire directive.

Mistake: Forgetting the semicolon. Fix: Every directive must end with a semicolon. Missing one can cause the browser to misinterpret your security rules.

Examples

Example scenario: Blocking all external embeds. If you want to ensure no other site can frame your page, use: Content-Security-Policy: frame-ancestors 'none';

Example scenario: Migrating to HTTPS. To force the browser to try HTTPS for every resource, even if the code says HTTP, use: Content-Security-Policy: upgrade-insecure-requests;

Example scenario: Nonce-based security. Generate a unique string for every page load and include it in your header: Content-Security-Policy: script-src 'nonce-random123'; Then, you apply that same string to your script tags: <script nonce="random123">.

FAQ

Can I use CSP with a static website? Yes. If you cannot change server headers, you can use a meta tag in your HTML. However, this method will not support clickjacking protection or violation reporting. For static sites, using hashes of your scripts is a reliable way to ensure only your approved code runs.

What happens if my CSP blocks a legitimate script? The browser will not execute the script, and the site might lose functionality. This appears as an error in the browser console. This is why you should always use "Report-Only" mode first to identify which scripts are being blocked before enforcing the policy.

What is the difference between a nonce and a hash? A nonce is a random string created for every page load. It works well for dynamic sites that can inject the nonce into script tags at runtime. A hash is a fixed signature of the script's content. Hashes are better for static sites because you do not need to change them unless you change the script itself.

Does CSP help with SEO? Indirectly, yes. CSP prevents site defacement and malicious redirects. If a site is hacked, search engines may flag it as "unsafe," which causes a massive drop in traffic. Effective security through CSP protects your search performance.

Is CSP a replacement for XSS prevention? No. You must still sanitize all user inputs and escape data before rendering it. CSP is the "defense in depth" that protects you if your primary coding defenses fail.

Start Your SEO Research in Seconds

5 free searches/day • No credit card needed • Access all features