0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
%

Content Security Policy: Prevent XSS & Data Injection

Content Security Policy, usually called CSP, is the most powerful security header available. While other security headers protect against specific attacks, CSP provides defense in depth against entire categories of attacks. Cross-site scripting. Data injection. Mixed content. Clickjacking. CSP addresses all of these and more.

The trade-off is complexity. CSP requires careful configuration. Set it too restrictive and you break your site. Set it too permissive and you do not get much protection. Done well, CSP is one of the strongest security measures available to websites.

This piece covers what CSP actually does, how it works, how to configure it properly, and how to avoid the pitfalls that catch people implementing it.

What CSP Does

CSP controls what content browsers are allowed to load and execute on your pages.

The Core Concept

When a browser loads a page from your site, it loads many resources. Scripts, styles, images, fonts, iframes, and more. Without CSP, the browser will load anything the page references.

With CSP, the browser checks each resource against the policy. Resources matching the policy get loaded. Resources not matching get blocked.

Why This Matters

Most successful XSS attacks work by getting malicious scripts onto pages. The attacker tricks the page into loading a script from somewhere they control, or injects script code directly into the page content.

With CSP, even if the attacker can get script code onto the page, the browser refuses to execute it because the source does not match the policy.

What CSP Restricts

A CSP can restrict many types of resources:

Scripts (script-src).

Styles (style-src).

Images (img-src).

Fonts (font-src).

Frames and iframes (frame-src, child-src).

Audio and video (media-src).

Plugins like Flash (object-src).

Connections to other servers via JavaScript (connect-src).

Forms (form-action).

Page embedding (frame-ancestors).

Each category can have its own policy. The CSP becomes a list of policies for each category.

How to Build a CSP

The configuration takes thought but follows patterns.

Start by Knowing What Your Site Loads

Before setting a policy, understand what your site actually needs. Inventory your scripts, styles, images, fonts, and other resources.

Browser developer tools show what gets loaded for each page. The Network tab is your friend.

For sites with multiple page types, audit each type. Home page, product page, blog post, checkout page. Different pages may load different resources.

Define Sources

CSP uses a list of allowed sources. Common values:

‘self’ allows resources from your own domain.

‘none’ allows nothing.

Specific URLs allow resources from those URLs.

‘unsafe-inline’ allows inline scripts and styles (use with caution).

‘unsafe-eval’ allows eval() and similar (avoid if possible).

Nonces and hashes allow specific scripts identified by nonce values or hashes of their content.

Write the Policy

A basic CSP for a simple site might look like:

Content-Security-Policy: default-src ‘self’; script-src ‘self’ https://www.google-analytics.com; style-src ‘self’ ‘unsafe-inline’; img-src ‘self’ data: https:; font-src ‘self’ https://fonts.gstatic.com;

This policy allows resources from the site itself, Google Analytics scripts, inline styles, images from the site or HTTPS sources, and fonts from Google Fonts.

The default-src directive provides a fallback for unspecified resource types.

Apply the Policy

The policy goes in the Content-Security-Policy HTTP header. For Apache:

Header set Content-Security-Policy “default-src ‘self’; script-src ‘self’ https://www.google-analytics.com; …”

For Nginx:

add_header Content-Security-Policy “default-src ‘self’; script-src ‘self’ https://www.google-analytics.com; …” always;

WordPress plugins can also handle CSP if server access is not available.

The CSP Report-Only Mode

Setting CSP wrong breaks sites. Report-only mode lets you test policies without enforcement.

How Report-Only Works

Instead of Content-Security-Policy, use Content-Security-Policy-Report-Only. The browser checks resources against the policy but does not block anything. Instead, it reports violations.

This lets you see what would be blocked under enforcement without actually breaking anything.

Setting Up Reporting

CSP reports go to a URL you specify. The reports tell you what resources would be blocked. You can review reports and adjust the policy.

Report-uri or report-to directives specify where reports go:

Content-Security-Policy-Report-Only: default-src ‘self’; report-uri /csp-report;

Services like report-uri.com collect and aggregate CSP reports if you do not want to handle them yourself.

Iterative Refinement

The workflow is:

Set a tight policy in report-only mode.

Review the reports.

Adjust the policy to allow legitimate resources you missed.

Repeat until reports show only actual policy violations.

Switch from report-only to enforcing mode.

This iterative approach prevents the all-or-nothing problem of CSP setup.

Common CSP Configurations

Different site types benefit from different policies.

Static Site

A simple static site might use:

Content-Security-Policy: default-src ‘self’; img-src ‘self’ data: https:; style-src ‘self’ ‘unsafe-inline’; script-src ‘self’;

Tight and focused. Few external resources needed.

WordPress Site

WordPress sites typically load resources from various sources. A starting policy:

Content-Security-Policy: default-src ‘self’ https:; script-src ‘self’ ‘unsafe-inline’ ‘unsafe-eval’ https:; style-src ‘self’ ‘unsafe-inline’ https:; img-src ‘self’ data: https:; font-src ‘self’ data: https:;

This is permissive because WordPress and its plugins often need flexibility. You can tighten over time.

Site With Many Third-Party Tools

If your site uses analytics, marketing tools, chat widgets, and other third-party services, the policy needs to allow each one:

Content-Security-Policy: default-src ‘self’; script-src ‘self’ https://www.google-analytics.com https://www.googletagmanager.com https://js.intercom.io; …

Each service requires research into what URLs it uses.

E-Commerce Site

E-commerce sites often have payment processors, fraud detection, and other specific tools. The policy must allow each:

Content-Security-Policy: default-src ‘self’; script-src ‘self’ https://js.stripe.com; frame-src https://js.stripe.com; …

For sites accepting payments, restricting form actions also matters:

form-action ‘self’ https://checkout.stripe.com;

Tricky CSP Cases

Some situations require special handling.

Inline Scripts & Styles

Many sites have inline scripts and styles for performance reasons. CSP blocks inline content by default.

Options:

Allow ‘unsafe-inline’ (weakens security but easiest).

Move content to external files.

Use nonces or hashes to allow specific inline content.

The nonce approach is most secure. Generate a random nonce for each page load. Add the nonce to script tags. Add the nonce to the CSP. Only scripts with the matching nonce can run.

This requires server-side support to generate nonces and include them in both the CSP header and the page HTML.

Third-Party Scripts That Load Other Scripts

Some third-party scripts (Google Tag Manager, for example) dynamically load other scripts. The dynamic loading can be hard to predict.

Two approaches:

Allow all sources broadly in your policy.

Use strict-dynamic, which allows scripts loaded by trusted scripts.

The strict-dynamic approach requires understanding how it works but provides better security.

WordPress Themes & Plugins

WordPress themes and plugins often add scripts and resources dynamically. Tracking all of them is hard.

Solutions:

Use a CSP plugin that handles WordPress specifics.

Maintain a permissive policy that allows what WordPress needs.

Audit and clean up plugins to reduce what your site loads.

Embedded Content

Embeds (YouTube videos, Twitter tweets, social widgets) often need specific CSP allowances.

For YouTube:

frame-src https://www.youtube.com;

For Twitter embeds, allow various Twitter domains.

Each embedded service needs research.

CSP Reporting & Monitoring

Even after deployment, monitoring matters.

Production Reports

Your CSP can continue sending reports even in enforcing mode. Reports show attempted policy violations, which can reveal:

Attack attempts (legitimate violations from attacks).

Browser bugs or compatibility issues.

Content you forgot to whitelist.

Drift in third-party services adding new URLs.

Volume Considerations

Sites with significant traffic generate many CSP reports. Browser extensions sometimes trigger reports. Network issues cause false reports.

Filter and aggregate reports to focus on real issues.

Updating Policies

CSP policies need maintenance. New third-party services added to the site need updates. Old services removed should be cleaned up.

Quarterly review of CSP policies catches drift.

Common CSP Mistakes

People stumble in predictable ways.

Going Too Aggressive Too Fast

Setting a tight CSP immediately on production usually breaks things. Use report-only mode first.

Using ‘unsafe-inline’ as the Default

Allowing ‘unsafe-inline’ largely defeats the XSS protection CSP provides. Use it only where necessary, and only for specific resource types.

Missing Subresources

The CSP must cover all resource types your site uses. Missing categories default to the default-src policy, which may be too restrictive.

Forgetting About Subdomains

Resources from subdomains need to be allowed explicitly. example.com does not automatically include cdn.example.com.

Not Monitoring

Setting up CSP and forgetting about it means missing important reports. Continued monitoring catches drift and attacks.

Mixing Report-Only & Enforcement Headers

You can have both Content-Security-Policy and Content-Security-Policy-Report-Only headers, but they work independently. Make sure your testing policy is in the right header.

When to Use CSP

CSP is not for every site. The configuration effort needs to match the protection value.

High-Value Targets

Sites that handle sensitive data benefit most from CSP. The protection against XSS is significant for sites where XSS would have serious consequences.

Sites With User-Generated Content

Sites where users contribute content (comments, profiles, forums) are higher XSS risk. CSP adds important defense.

Sites With Many Third-Party Integrations

Surprisingly, sites with many integrations sometimes benefit most from CSP because it forces deliberate decisions about what gets loaded.

Simple Brochure Sites

For simple sites without user input and few external dependencies, the CSP value-to-effort ratio is lower. The basic security headers may be enough.

Bringing CSP Strategy Together

Content Security Policy is the most powerful security header but also the most complex. Done well, it provides strong defense against multiple attack categories. Done poorly, it breaks sites or provides false security.

For most sites that decide to implement CSP, the right approach is iterative. Start in report-only mode. Review reports. Adjust the policy. Repeat until the policy is solid. Then switch to enforcement.

The setup work is real but bounded. Most CSP implementations take a few hours to set up and a few weeks of monitoring and refinement before going to enforcement.

The protection that CSP provides is meaningful. Sites with proper CSP have dramatically reduced XSS attack surfaces. The same vulnerability that would lead to widespread account compromise on a site without CSP often produces little impact on a site with CSP.

For sites that have decided security matters, CSP is worth implementing. The work is bounded. The benefits compound across the life of the site. The investment in time pays back in incidents that do not happen.

If your site has not implemented CSP, evaluating whether to add it is worthwhile. Consider what attacks would be most damaging. Consider what content your site loads. Consider the maintenance effort. For sites where the protection justifies the investment, CSP is one of the more effective security measures available. The starting point is usually report-only mode and patient iteration. From there, sites move toward properly enforced CSP that provides genuine defense against the attacks the policy is designed to stop.

Content Security Policy Prevent XSS & Data Injection

Table of Contents

Project Details

Ready to go from zero to live? Fill out the form below or book a free 15-minute call. We respond within 24 hours, usually sooner.
Traffic Spikes: How to Handle Sudden Popularity

Most websites get steady traffic that grows slowly over time. Then occasionally, something happens. A press mention. A viral social post. A product launch. A celebrity tweet. Traffic that was a few hundred visitors per day suddenly becomes 50,000 visitors in an hour. That kind of moment is exactly when

Website Maintenance Checklist: Monthly Tasks

The previous piece covered why website maintenance matters and what it generally includes. This piece gets practical. Here is a detailed monthly maintenance checklist with 20 specific tasks that keep most websites healthy. Some tasks only take minutes. Some take longer. Together they form a complete monthly maintenance routine. Adapt

Scalability: Hosting That Grows With Your Business

When you launch a website, you usually have no idea how big it will get. Maybe it stays small forever. Maybe it grows steadily. Maybe one piece of content takes off and your traffic jumps 50x in a week. The hosting choice you make on day one usually does not