Learn about Content Security Policy (CSP), its importance, how it works, and how it enhances web security.
Content Security Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, particularly Cross-Site Scripting (XSS) and data injection attacks, by controlling the resources a web page is allowed to load.
CSP is implemented via an HTTP header, allowing web developers to explicitly specify which origins the browser should consider as trusted sources of content. This helps prevent malicious scripts or other harmful content from being executed in the user's browser.
Modern web applications often use scripts, stylesheets, images, and media files from various sources. This complexity provides opportunities for attackers to inject malicious code, with XSS being one of the most common attack vectors. XSS attacks can compromise user sessions, sensitive information, or the website itself.
CSP plays a crucial role in mitigating these threats in several ways:
frame-ancestors
directive controls how other sites can frame the page, thus preventing clickjacking attacks.The web server sends the Content-Security-Policy
HTTP header to the client (browser). This header contains a set of policy directives, which are rules for the resources the page is allowed to load.
For example, the following CSP header allows scripts to be loaded only from the current domain ('self'
) and blocks scripts from all other origins:
Content-Security-Policy: script-src 'self';
When the browser receives this header, it enforces the policy for all resource requests on the page. If an attempt is made to load a resource that violates the policy, the browser blocks that resource and can send a violation report to a specified endpoint.
CSP offers various directives for fine-grained control over resource types. Some key directives include:
default-src
: Sets a default policy for many other directives. If a specific directive is not set, this value is used.script-src
: Specifies valid sources for JavaScript code.style-src
: Specifies valid sources for CSS stylesheets.img-src
: Specifies valid sources for images.font-src
: Specifies valid sources for fonts.media-src
: Specifies valid sources for media files like audio and video.connect-src
: Restricts origins that can be connected to using fetch
, XMLHttpRequest
, WebSocket
, EventSource
, etc.frame-src
: Specifies valid sources that can be embedded as frames. (Deprecated, child-src
is recommended).child-src
: Specifies valid sources for nested browsing contexts, such as web workers and frames.object-src
: Controls valid sources for <object>
, <embed>
, and <applet>
tags. It's recommended to set this to 'none'
for security reasons.frame-ancestors
: Specifies valid parent origins that can embed the current page using frames, iframes, objects, embeds, or applets. This is crucial for defending against clickjacking attacks.report-uri
/ report-to
: Specifies a URL where the browser will send reports when a CSP violation occurs. report-to
is a newer directive that supports JSON-formatted reports and supersedes report-uri
.Each directive can have source values such as:
'self'
: Allows the current origin (same scheme, host, and port).'unsafe-inline'
: Allows inline JavaScript (<script>...</script>
) and inline CSS (<style>...</style>
, style
attribute). Its use should be minimized due to security risks.'unsafe-eval'
: Allows text-to-JavaScript mechanisms like eval()
. Its use should be minimized due to security risks.'none'
: Allows no sources.https://example.com
: Allows a specific domain.*.example.com
: Allows all subdomains of example.com.data:
: Allows resources using the data:
scheme (e.g., base64-encoded images).nonce-<base64-value>
: Allows scripts or styles with a specific cryptographic nonce (number used once). The server must generate a unique nonce for each request and include it in the header and script tags.sha256-<base64-value>
: Allows inline scripts or styles that match a specific hash value.CSP can primarily be applied in two ways:
HTTP Header: This is the most recommended method. Set the Content-Security-Policy
header in your web server configuration (e.g., Apache, Nginx) or backend application code.
add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://trusted-cdn.com";
Header set Content-Security-Policy "default-src 'self'; script-src 'self' https://trusted-cdn.com"
<meta>
Tag: You can define CSP using a <meta>
tag in the <head>
section of your HTML document.
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://trusted-cdn.com;">
However, using the <meta>
tag has some limitations, such as not supporting frame-ancestors
, report-uri
, and sandbox
directives. Therefore, using the HTTP header method is preferred whenever possible.
When first introducing CSP, a strict policy might break existing website functionality. Therefore, a gradual rollout is crucial.
Report-Only Mode: Use the Content-Security-Policy-Report-Only
header to receive violation reports without enforcing the policy. This helps identify what resources are currently being loaded and adjust the policy accordingly.
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-violation-report-endpoint;
Gradual Policy Tightening: Start with a lenient policy (e.g., default-src 'self' 'unsafe-inline' https: data:
) and gradually tighten it by analyzing violation reports. The goal is to eliminate 'unsafe-inline'
and 'unsafe-eval'
and specify sources as precisely as possible.
Use Nonces or Hashes: If inline scripts or styles are absolutely necessary, use nonce or hash-based approaches instead of 'unsafe-inline'
to enhance security.
Continuous Monitoring and Updates: A CSP policy is not a set-it-and-forget-it solution. As your website changes, the policy must be updated accordingly. Regularly monitor violation reports and adjust the policy as needed.
frame-ancestors
.Content Security Policy (CSP) is an essential part of modern web application security. It provides a powerful mechanism to protect users and data from common web attacks like XSS. While implementing and maintaining CSP can be somewhat complex, the security benefits it offers are significant. A gradual rollout strategy and continuous monitoring can greatly improve your website's security posture.