Content Security Policy Guide For XSS Attack Protection
Posted: April 9, 2025 | Last updated: April 9, 2025Create Your Content Security Policy In Seconds
Don't want to write complex CSP headers manually? Use our interactive tool to generate a secure policy with just a few clicks.
Launch CSP Generator ToolTable of Contents
What is a Content Security Policy?
A Content Security Policy (CSP) is a critical security feature that helps protect your website from various types of attacks, particularly Cross-Site Scripting (XSS) and data injection attacks. Think of it as a security guard for your website that strictly controls which resources are allowed to load and execute.
In simple terms, CSP is an added layer of security that helps detect and mitigate certain types of attacks, including Cross-Site Scripting (XSS) and data injection attacks. These attacks are used for everything from data theft to site defacement or malware distribution.
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com
The above example is a basic CSP header that tells browsers to:
- By default, load resources only from the same origin as the page itself (
'self'
) - Load scripts only from the same origin and from
https://trusted-cdn.com
This simple policy already provides significant protection against many types of attacks by preventing malicious scripts from executing, even if an attacker manages to inject them into your site.
Need help creating a CSP? Writing Content Security Policies manually can be error-prone. Try our CSP Generator to create a secure policy without needing to memorize all the syntax.
Why You Should Use CSP
Despite advances in web security, Cross-Site Scripting (XSS) remains one of the most prevalent web vulnerabilities. According to the OWASP Top 10, XSS attacks continue to be a major threat to web applications. Here's why implementing a Content Security Policy is essential:
Benefits of Implementing CSP
- Protection Against XSS Attacks: CSP can block most types of XSS attacks by controlling which scripts can execute on your page.
- Data Theft Prevention: By restricting which domains can receive data from your site, CSP helps prevent unauthorized data exfiltration.
- Control Over External Resources: CSP gives you precise control over which external resources (scripts, styles, fonts, etc.) can be loaded.
- Secure Iframe Embedding: Control which sites can be embedded in iframes on your pages, preventing clickjacking attacks.
- Violation Reporting: CSP can be configured to report violations, helping you identify potential security issues.
- SEO Benefits: Google considers security in its ranking algorithms. Implementing CSP demonstrates your commitment to security.
Did you know? According to a study by Google, properly implemented CSP can prevent 95% of XSS attacks. The remaining 5% typically require additional security measures like input validation and output encoding.
How CSP Works
Content Security Policy works by declaring a set of content restrictions that the browser enforces. When a CSP is in place, the browser will only execute or render resources from whitelisted sources.
Here's a simplified explanation of the process:
- You define a CSP by setting a
Content-Security-Policy
HTTP header on your web server or via a<meta>
tag in your HTML. - The policy contains directives that specify which resources can be loaded and from where.
- When the browser receives the policy, it enforces these rules for all resources on the page.
- If a resource violates the policy, the browser blocks it from loading and logs a warning in the console.
- Optionally, policy violations can be reported to a specified URL for monitoring.
CSP introduces an additional layer of security that helps mitigate the damage that can be done by content injection vulnerabilities. Even if an attacker manages to find an XSS vulnerability, the CSP can prevent the injected script from loading or executing.
<!-- CSP implemented via meta tag --><meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
The example above sets a CSP that:
- Allows resources to be loaded only from the same origin by default
- Allows images to be loaded from any HTTPS source
- Prevents loading any child frames (iframes)
Creating an effective CSP requires careful consideration of all the resources your website uses. If you find this process complex, our CSP Generator tool can simplify it by helping you build a policy that covers your specific needs.
Need Help Creating Your Content Security Policy?
CSP syntax can be complex and error-prone. Our interactive generator makes it easy to build a comprehensive policy for your website - no security expertise required!
Use the CSP Generator ToolUnderstanding CSP Directives
CSP uses "directives" to control different types of resources. Each directive specifies which sources are allowed for a particular type of resource. Let's explore the most important directives:
Essential Directives
Directive | Controls | Example | HTML Example |
---|---|---|---|
default-src | Fallback for all other fetch directives | default-src 'self' | Applies to all resource types if not specified elsewhere |
script-src | JavaScript sources | script-src 'self' https://cdn.example.com | <script src="https://cdn.example.com/script.js"> |
style-src | CSS stylesheet sources | style-src 'self' https://fonts.googleapis.com | <link href="https://fonts.googleapis.com/css" rel="stylesheet"> |
img-src | Image sources | img-src 'self' https://images.example.com | <img src="https://images.example.com/photo.jpg"> |
connect-src | URLs for fetch, WebSocket, and XMLHttpRequest | connect-src 'self' https://api.example.com | fetch('https://api.example.com/data') |
font-src | Font sources | font-src 'self' https://fonts.gstatic.com | @font-face { src: url('https://fonts.gstatic.com/font.woff2'); } |
frame-src | Sources for frames and iframes | frame-src 'self' https://youtube.com | <iframe src="https://youtube.com/embed/video"> |
Managing multiple directives can be challenging. Our CSP Generator helps you easily configure each directive without memorizing all the options.
Additional Directives
Directive | Controls | Example | Usage |
---|---|---|---|
base-uri | Restricts URLs for <base> element | base-uri 'self' | Control which URLs can be used in <base href="..."> |
form-action | Restricts where forms can submit to | form-action 'self' | Control where <form action="..."> can submit to |
object-src | Controls <object> , <embed> , and <applet> sources | object-src 'none' | Usually set to 'none' for security unless specifically needed |
media-src | Sources for <audio> and <video> elements | media-src 'self' https://media.example.com | Control media sources like <video src="..."> |
worker-src | Sources for Worker, SharedWorker, or ServiceWorker scripts | worker-src 'self' | Control sources for new Worker("worker.js") |
manifest-src | Sources for web app manifests | manifest-src 'self' | Control sources for <link rel="manifest" href="..."> |
report-uri / report-to | Where to send CSP violation reports | report-uri /csp-report-endpoint | Collect violation reports at a specified endpoint |
Special Values for Directives
CSP directives accept several special values that control behavior:
'self'
- Allows resources from the same origin (same scheme, host, and port)'none'
- Blocks all resources of the specified type'unsafe-inline'
- Allows inline scripts or styles (not recommended for security)'unsafe-eval'
- Allows the use ofeval()
and similar functions (not recommended)'nonce-[random]'
- Allows specific inline scripts with matching nonce attributes'sha256-[hash]'
- Allows specific inline scripts that match the given hashhttps:
- Allows loading resources from any HTTPS sourcedata:
- Allows loading resources from data: URIs (use with caution)
Security Warning: Using 'unsafe-inline'
and 'unsafe-eval'
significantly reduces the security benefits of CSP. Use nonces or hashes instead of 'unsafe-inline'
when possible, and restructure your code to avoid 'unsafe-eval'
.
Implementing CSP
There are two main ways to implement a Content Security Policy:
- HTTP Header - Set by your web server (recommended method)
- HTML Meta Tag - Embedded directly in your HTML
The HTTP header approach is preferred because it ensures the policy is applied before any content is parsed, providing better protection. Here's how to implement CSP on different platforms:
Apache (.htaccess)
Add the following to your .htaccess
file:
# Enable Content Security PolicyHeader set Content-Security-Policy "default-src 'self'; script-src 'self' https://trusted-cdn.com; style-src 'self' https://trusted-styles.com; img-src 'self' https://trusted-images.com data:; font-src 'self' https://trusted-fonts.com; connect-src 'self' https://api.example.com"
Make sure the mod_headers
module is enabled in your Apache configuration.
If you're finding CSP implementation in Apache challenging, our CSP Generator tool can create the exact code you need for your .htaccess file.
Nginx
Add the following to your Nginx configuration file (usually located at /etc/nginx/sites-available/your-site
):
server { # Other server configurations... add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://trusted-cdn.com; style-src 'self' https://trusted-styles.com; img-src 'self' https://trusted-images.com data:; font-src 'self' https://trusted-fonts.com; connect-src 'self' https://api.example.com";}
After making changes, reload or restart Nginx:
sudo nginx -t && sudo systemctl reload nginx
IIS (web.config)
Add the following to your web.config
file:
<system.webServer> <httpProtocol>
<customHeaders>
<add name="Content-Security-Policy" value="default-src 'self'; script-src 'self' https://trusted-cdn.com; style-src 'self' https://trusted-styles.com; img-src 'self' https://trusted-images.com data:; font-src 'self' https://trusted-fonts.com; connect-src 'self' https://api.example.com">
</customHeaders>
</httpProtocol>
</system.webServer>
PHP
Add the following to the top of your PHP files (before any output is sent to the browser):
< ?php
// Set Content Security Policyheader("Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com; style-src 'self' https://trusted-styles.com; img-src 'self' https://trusted-images.com data:; font-src 'self' https://trusted-fonts.com; connect-src 'self' https://api.example.com");
?>
For more advanced setups with nonces, you can use:
< ?php
// Generate a random nonce for scripts
\$scriptNonce = base64_encode(random_bytes(16));
// Set Content Security Policy with nonce
header("Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{\$scriptNonce}'; style-src 'self'");
?><
!-- Later in your HTML -->
<script nonce="< ?php echo \$scriptNonce;?>">
// Your inline JavaScript here
</script>
HTML Meta Tag
Add this to the <head>
section of your HTML:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://trusted-cdn.com; style-src 'self' https://trusted-styles.com; img-src 'self' https://trusted-images.com data:; font-src 'self' https://trusted-fonts.com; connect-src 'self' https://api.example.com">
While this method is simpler for testing, the HTTP header approach is generally preferred for production environments as it provides better security.
Creating custom CSP implementations for each server type can be error-prone. Our CSP Generator provides platform-specific code for Apache, Nginx, IIS, and PHP after you configure your policy.
Testing with Report-Only Mode
Before fully implementing a Content Security Policy, it's wise to test it in "report-only" mode. This allows you to see what would be blocked without actually blocking anything, helping you identify potential issues before they affect your users.
How to Enable Report-Only Mode
Instead of using Content-Security-Policy
, use Content-Security-Policy-Report-Only
:
# Apache (.htaccess)Header set Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' https://trusted-cdn.com; report-uri /csp-violation-report-endpoint/"
Setting Up a Reporting Endpoint
To collect violation reports, you need to establish an endpoint that can receive and process them. Here's a simple PHP example:
< ?php// csp-report-endpoint.php// Get the raw POST data$json = file_get_contents('php://input');// Decode the JSON$cspReport = json_decode($json, true);// Log the violation$logFile = 'csp-violations.log';$logEntry = date('Y-m-d H:i:s') . ' - ' . json_encode($cspReport['csp-report']) . PHP_EOL;file_put_contents($logFile, $logEntry, FILE_APPEND);// Respond with 204 No Contenthttp_response_code(204);?>
Then add the reporting endpoint to your CSP:
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' https://trusted-cdn.com; report-uri /csp-report-endpoint.php
Analyzing Violation Reports
CSP violation reports contain valuable information, including:
- The violated directive
- The blocked URI
- The document URI where the violation occurred
- The referrer
- The user agent
By analyzing these reports, you can identify and fix issues before enabling the full blocking mode of CSP.
Pro tip: Run in report-only mode for at least a week while monitoring all site functionality to catch potential issues. Our CSP Generator can create both enforcement and report-only versions of your policy.
Best Practices
Implementing an effective Content Security Policy involves more than just adding headers. Follow these best practices to maximize security while minimizing disruption:
Start with Report-Only Mode
Always begin with Content-Security-Policy-Report-Only
to identify potential issues before enforcing restrictions.
Use the Principle of Least Privilege
Only allow the specific resources your site actually needs. Avoid overly permissive directives like *
when more specific sources can be used.
Avoid 'unsafe-inline' and 'unsafe-eval'
These significantly reduce the security benefits of CSP. Instead:
- Use nonces or hashes for inline scripts
- Move inline scripts to external files
- Refactor code to avoid
eval()
and similar functions
Use HTTPS Everywhere
When specifying sources, use HTTPS URLs whenever possible. Consider adding upgrade-insecure-requests
directive to automatically upgrade HTTP requests to HTTPS.
Set object-src to 'none'
Unless you specifically need <object>
, <embed>
, or <applet>
elements, set object-src: 'none'
to prevent potential attack vectors.
Implement a Strict Policy
Start with a strict policy (default-src 'none'
) and then explicitly allow only what you need.
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self'; font-src 'self'; connect-src 'self'; form-action 'self'; base-uri 'self';
Monitor Violation Reports
Set up logging for CSP violations to identify and fix legitimate resources that might be blocked.
Test Thoroughly
Test all functionality after implementing CSP, including forms, AJAX requests, third-party integrations, and admin functionalities.
Need help implementing these best practices? Our CSP Generator tool follows security best practices by default while creating a policy that works for your specific needs.
Real-World Examples
Here are some example Content Security Policies for common scenarios:
Basic Website (HTML, CSS, JavaScript)
Content-Security-Policy: default-src 'self'; img-src 'self' data:; object-src 'none'
Website Using Google Fonts and Analytics
Content-Security-Policy: default-src 'self'; font-src 'self' https://fonts.gstatic.com; style-src 'self' https://fonts.googleapis.com; script-src 'self' https://www.googletagmanager.com https://www.google-analytics.com; img-src 'self' https://www.google-analytics.com; connect-src 'self' https://www.google-analytics.com
WordPress Site
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.googletagmanager.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https://www.google-analytics.com; connect-src 'self' https://www.google-analytics.com
Note that WordPress often requires 'unsafe-inline'
and 'unsafe-eval'
due to how plugins and themes function. Work on improving this over time by moving toward nonces and external scripts.
E-commerce Site
Content-Security-Policy: default-src 'self'; script-src 'self' https://js.stripe.com https://www.paypal.com https://www.googletagmanager.com; style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https://www.google-analytics.com https://img.youtube.com; frame-src 'self' https://www.youtube.com https://js.stripe.com https://www.paypal.com; connect-src 'self' https://api.stripe.com https://www.paypal.com https://www.google-analytics.com
Single Page Application
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; connect-src 'self' https://api.example.com; img-src 'self' data:; object-src 'none'; base-uri 'self'; form-action 'self'
These examples are starting points. Your specific needs may vary based on third-party integrations and functionality. Our CSP Generator can help you create a custom policy for your exact requirements.
Using Our CSP Generator Tool
Creating a Content Security Policy from scratch can be challenging. Our interactive CSP Generator simplifies this process by helping you build a comprehensive policy tailored to your website.
Benefits of Our CSP Generator
- User-friendly interface - No need to memorize complex CSP syntax
- Pre-configured templates for common services like Google Analytics, Google Fonts, etc.
- Server-specific output - Generate code for Apache, Nginx, IIS, or PHP
- Report-Only option - Test your policy before full implementation
- Educational tooltips - Learn about CSP as you build your policy
Ready to Create Your Content Security Policy?
Our generator tool makes it easy to build a secure, comprehensive CSP without having to memorize all the directives and syntax.
Create Your CSP NowThe tool walks you through each directive, allowing you to select which resources to allow. It then generates the appropriate code for your server environment, ready to implement.
Common Issues & Solutions
When implementing Content Security Policy, you might encounter these common issues:
Inline Scripts and Styles Being Blocked
Problem: CSP blocks inline scripts and styles by default, which can break functionality.
Solutions:
- Move inline code to external files (preferred)
- Use nonces for necessary inline scripts:
script-src 'self' 'nonce-random123'
- Use hashes:
script-src 'self' 'sha256-hashOfYourScript'
- As a last resort, use
'unsafe-inline'
(reduces security)
Third-Party Resources Being Blocked
Problem: Scripts, styles, or other resources from third-party domains are blocked.
Solution: Add the required domains to the appropriate directives. Use the browser console to identify blocked resources.
Content-Security-Policy: default-src 'self'; script-src 'self' https://third-party-domain.com;
eval() and Function() Being Blocked
Problem: Some libraries and frameworks use eval()
or Function()
, which CSP blocks by default.
Solutions:
- Use alternative libraries that don't require eval
- Refactor your code to avoid dynamic code execution
- If absolutely necessary, add
'unsafe-eval'
to script-src
Dynamic Resources and Data URIs
Problem: Resources loaded with data URIs (like inline SVGs) are blocked.
Solution: Add data:
to the appropriate directive:
Content-Security-Policy: default-src 'self'; img-src 'self' data:;
CSP Not Working at All
Problem: Your CSP appears to have no effect on the browser.
Solutions:
- Check that the header is properly configured
- Verify there are no syntax errors in your policy
- Ensure no HTML is output before your PHP header() calls
- Check for duplicate or conflicting CSP headers
For more complex websites, using our CSP Generator tool can help identify and resolve these issues before they occur.
Conclusion
Content Security Policy is a powerful security feature that can significantly reduce the risk of Cross-Site Scripting (XSS) and other types of attacks on your website. While implementing CSP requires some initial effort, the security benefits far outweigh the costs.
Remember these key points:
- Start with report-only mode to identify potential issues
- Be as specific as possible with your directives
- Avoid 'unsafe-inline' and 'unsafe-eval' when possible
- Test thoroughly after implementation
- Monitor for CSP violations and update your policy as needed
By following the guidelines in this article and using our CSP Generator tool, you can implement a robust Content Security Policy that protects your website and users from a wide range of attacks.
Ready to Secure Your Website?
Create a custom Content Security Policy for your website with our easy-to-use generator tool.
Get Started with the CSP Generator