Ctrl + K
Security10 min read

Content Security Policy (CSP) Explained

Understand how Content Security Policy helps secure websites against common web attacks.

Published: 2026-06-22

Modern websites load resources from many different places. JavaScript files, stylesheets, images, fonts, APIs and third-party services are often pulled from multiple domains. While this flexibility enables powerful web applications, it also creates security risks. One compromised script or malicious injection can potentially expose user data, hijack sessions or execute unwanted code in visitors' browsers.

Content Security Policy, commonly known as CSP, was created to reduce these risks. It provides website owners with a powerful mechanism for controlling which resources browsers are allowed to load and execute.

What Is Content Security Policy?

Content Security Policy is a browser security feature that allows website owners to define trusted sources for scripts, styles, images, fonts, frames and other resources.

Instead of allowing content to load from anywhere on the internet, a CSP restricts resource loading to approved locations. If a browser encounters a resource that violates the policy, it blocks that resource automatically.

CSP acts as an additional security layer that helps protect websites even when vulnerabilities exist elsewhere in the application.

Why CSP Was Created

One of the biggest threats to web applications is Cross-Site Scripting (XSS). XSS attacks occur when attackers manage to inject malicious JavaScript into a page viewed by other users.

Without additional protections, browsers typically execute injected scripts because they appear to be part of the page.

CSP helps reduce the impact of these attacks by specifying exactly which scripts are allowed to run. Even if malicious code is injected, the browser may refuse to execute it because it does not match the policy.

How CSP Works

A Content Security Policy is sent to the browser through an HTTP response header or a meta tag. The policy contains a set of directives that define permitted resource sources.

When the browser loads the page, it compares every requested resource against the policy. Resources that comply are loaded normally. Resources that violate the policy are blocked.

This validation occurs automatically without requiring any user interaction.

A Simple CSP Example

A basic policy might look like this:

Content-Security-Policy: default-src 'self'

This policy instructs the browser to load all resources only from the same origin as the website itself.

External scripts, stylesheets, images and other resources from different domains would be blocked unless explicitly allowed.

The Most Important CSP Directives

default-src

The fallback directive used when no more specific directive is provided.

default-src 'self'

This is usually the foundation of most CSP configurations.

script-src

Controls which JavaScript sources are allowed.

script-src 'self' https://cdn.example.com

Only scripts from the website itself and the specified CDN can execute.

style-src

Controls stylesheet sources.

style-src 'self' https://fonts.googleapis.com

img-src

Controls image loading sources.

img-src 'self' data: https:

This configuration allows local images, data URLs and HTTPS images.

font-src

Controls font sources.

font-src 'self' https://fonts.gstatic.com

connect-src

Controls API requests, WebSocket connections and fetch requests.

connect-src 'self' https://api.example.com

frame-ancestors

Defines which websites may embed your page inside an iframe.

frame-ancestors 'none'

This prevents clickjacking attacks by disallowing embedding entirely.

object-src

Controls plugins such as Flash or embedded objects.

object-src 'none'

Most modern websites disable object loading completely.

Protecting Against XSS

CSP is most famous for its ability to mitigate Cross-Site Scripting attacks.

Suppose an attacker injects the following code into a vulnerable page:

<script>alert('Hacked')</script>

If the site's CSP only allows scripts from approved sources and does not allow inline scripts, the browser blocks the injected code instead of executing it.

This significantly reduces the impact of many common XSS vulnerabilities.

The Dangers of 'unsafe-inline'

One directive deserves special attention: unsafe-inline.

script-src 'self' 'unsafe-inline'

Adding unsafe-inline allows inline JavaScript to execute. While this may improve compatibility with older applications, it weakens CSP's protection against XSS attacks.

Whenever possible, developers should avoid using unsafe-inline and instead move scripts into separate files or use nonces and hashes.

Using Nonces

A nonce is a unique value generated for each page request. The browser only executes inline scripts that contain the correct nonce.

<script nonce="abc123">
console.log("Safe script");
</script>

This allows specific inline scripts to run while blocking injected scripts that lack the correct nonce.

Using Hashes

Another approach is using script hashes. Instead of allowing all inline scripts, the policy specifies the hash of approved script content.

Only scripts matching the exact hash can execute.

Hashes provide strong security but can become difficult to maintain when script contents change frequently.

CSP Reporting

Content Security Policy supports reporting mechanisms that notify website owners when violations occur.

This allows developers to identify blocked resources, detect attacks and refine policies without disrupting users.

Many organizations deploy CSP in report-only mode initially before enabling full enforcement.

Report-Only Mode

Instead of blocking violations immediately, browsers can simply report them.

Content-Security-Policy-Report-Only: default-src 'self'

This helps developers test policies safely before enforcing restrictions that could accidentally break parts of a website.

Common CSP Mistakes

Many websites deploy CSP incorrectly and lose much of its security value.

One common mistake is using overly permissive directives such as allowing resources from every domain or enabling unsafe-inline everywhere.

Another issue is forgetting to update the policy when introducing new third-party services, which can cause legitimate resources to be blocked.

A good CSP should be restrictive enough to improve security while still allowing required functionality.

Example of a Strong CSP

Content-Security-Policy:
default-src 'self';
script-src 'self';
style-src 'self';
img-src 'self' data: https:;
font-src 'self';
connect-src 'self';
object-src 'none';
frame-ancestors 'none';
base-uri 'self';
form-action 'self';

This policy represents a strong starting point for many modern websites.

Conclusion

Content Security Policy is one of the most effective browser security features available today. It helps protect websites against XSS attacks, unauthorized resource loading, clickjacking and several other threats.

Although configuring CSP can initially seem complex, even a basic policy provides meaningful security improvements. By gradually tightening resource permissions, avoiding unsafe-inline where possible and monitoring violation reports, developers can significantly strengthen the security posture of their web applications.

Related Tools