Content Security Policy (CSP) is one of the most effective mechanisms for mitigating Cross-Site Scripting (XSS) attacks, especially when input sanitization alone isn't enough. Introduced as a W3C standard and supported by most modern browsers, CSP lets you precisely define which resources a web page is allowed to load and execute. This way, even if a malicious script manages to get injected into the DOM, the browser can block its execution.

What is a Content Security Policy

CSP is an HTTP header that specifies a set of directives. Each directive controls a type of content (scripts, images, stylesheets, fonts, etc.) and defines its allowed sources. For example, the script-src directive determines from which origins JavaScript can be loaded and executed.

A basic configuration might look like this:

Header set Content-Security-Policy "default-src 'self'; script-src 'self'"

This policy allows loading all resources only from the same domain ('self') and prevents scripts from external sources from executing.

Practical examples and advanced configurations

For more complex environments, the policy can be extended with additional directives:

Header set Content-Security-Policy "default-src 'self'; script-src 'self' https://cdn.example.com; object-src 'none'; frame-ancestors 'none'"

In this example:

  • script-src allows scripts to run only from the site's own domain and a specific CDN.

  • object-src 'none' disables the use of plugins like Flash or Java applets.

  • frame-ancestors 'none' prevents the page from being loaded inside an iframe, protecting against clickjacking attacks.

Report-Only mode

Before applying a restrictive policy in production, it's advisable to test it in "report-only" mode. This way, the browser doesn't block non-compliant resources, but sends a report to a configured endpoint:

Header set Content-Security-Policy-Report-Only "default-src 'self'; report-uri /csp-report-endpoint"

This approach lets you monitor potential violations without affecting the user experience.

Best practices

  • Avoid using unsafe-inline and unsafe-eval, which undo most of the protection CSP provides.

  • Use nonces or hashes to safely authorize inline scripts.

  • Combine CSP with proper input and output sanitization.

  • Monitor CSP reports to identify attack attempts or misconfigurations.

Content Security Policy doesn't replace other security measures, but it represents an essential additional layer of defense. Our article on XSS showed how malicious scripts can be injected through unsanitized input; CSP steps in at precisely that stage, preventing execution even where vulnerabilities exist in the code.