How to Check Content Security Policy Headers with OpDeck's Scanner
If you're trying to check Content Security Policy headers on your website, you're already thinking about security the right way. CSP headers are one of the most effective defenses against cross-site scripting (XSS) attacks, clickjacking, and data injection — but only if they're correctly configured and actually present. This guide walks you through exactly how to check Content Security Policy headers, what to look for, how to interpret the results, and how to fix common misconfigurations.
What Is a Content Security Policy Header?
A Content Security Policy (CSP) is an HTTP response header that tells browsers which content sources are trusted for your web page. When a browser loads your site, it checks the CSP header and blocks any resources — scripts, stylesheets, images, fonts, iframes — that don't match the policy you've defined.
Here's a simple example of what a CSP header looks like in an HTTP response:
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src *;
Breaking that down:
default-src 'self'— By default, only load resources from the same originscript-src 'self' https://cdn.example.com— Scripts can only come from your domain or that specific CDNstyle-src 'self' 'unsafe-inline'— Styles can come from your domain or be inline (thoughunsafe-inlineweakens protection)img-src *— Images can be loaded from anywhere
Without a CSP header, browsers apply no restrictions on resource loading, leaving your users vulnerable to injected malicious scripts.
Why Checking Your CSP Header Matters
Many developers assume that because they set a CSP header during initial deployment, it's still there and working correctly. That assumption can be dangerous. Headers can be:
- Accidentally removed during server migrations or deployments
- Overridden by CDN configurations or reverse proxies
- Too permissive due to rushed debugging sessions where
unsafe-inlineorunsafe-evalwere added and never removed - Broken by third-party integrations that require additional sources you forgot to whitelist
Regularly checking your CSP header ensures your security posture hasn't quietly degraded. It also helps you catch overly broad policies that give a false sense of security.
How to Check Content Security Policy Headers: Multiple Methods
There are several ways to check Content Security Policy headers, ranging from browser developer tools to command-line utilities to dedicated security scanners. Each approach has its use case.
Method 1: Using Browser Developer Tools
The quickest way to check a CSP header for any website is through your browser's built-in developer tools.
Steps for Chrome or Firefox:
- Open the website you want to inspect
- Press
F12(orCtrl+Shift+Ion Windows,Cmd+Option+Ion Mac) to open DevTools - Click on the Network tab
- Reload the page (
F5orCmd+R) - Click on the first document request (usually the HTML file at the top of the list)
- Select the Headers tab in the right panel
- Scroll down to the Response Headers section and look for
content-security-policy
If you see the header, you'll get its full value. If it's absent, that's a red flag worth addressing immediately.
What to look for:
- Is the header present at all?
- Does it use
Content-Security-Policy(enforced) orContent-Security-Policy-Report-Only(monitoring mode only)? - Are there any obviously dangerous directives like
script-src *ordefault-src *?
Method 2: Using cURL from the Command Line
For developers comfortable with the terminal, curl is a fast way to fetch and inspect headers directly.
curl -I https://yourdomain.com
The -I flag sends a HEAD request and returns only the headers. Look for the content-security-policy line in the output.
Example output:
HTTP/2 200
content-type: text/html; charset=UTF-8
x-frame-options: SAMEORIGIN
content-security-policy: default-src 'self'; script-src 'self' 'nonce-abc123'; object-src 'none'
x-content-type-options: nosniff
strict-transport-security: max-age=31536000; includeSubDomains
If you want to filter just the CSP line:
curl -sI https://yourdomain.com | grep -i content-security-policy
This returns nothing if no CSP header is set — which itself tells you something important.
You can also use curl with the -v flag for verbose output, which shows the full request/response cycle including all headers:
curl -v https://yourdomain.com 2>&1 | grep -i "content-security"
Method 3: Using Python for Automated Checks
If you're auditing multiple pages or want to integrate CSP checking into a CI/CD pipeline, Python makes it straightforward:
import requests
def check_csp(url):
try:
response = requests.get(url, timeout=10)
headers = response.headers
csp = headers.get('Content-Security-Policy')
csp_report_only = headers.get('Content-Security-Policy-Report-Only')
if csp:
print(f"[ENFORCED CSP FOUND]\n{csp}\n")
elif csp_report_only:
print(f"[REPORT-ONLY CSP FOUND — Not enforced]\n{csp_report_only}\n")
else:
print("[WARNING] No Content-Security-Policy header found.")
except requests.RequestException as e:
print(f"Error fetching {url}: {e}")
check_csp("https://yourdomain.com")
You can extend this to loop through a list of URLs from a sitemap, check subdomains, or log results to a file for periodic audits.
Method 4: Using OpDeck's Vulnerability Scanner
The most thorough and beginner-friendly way to check Content Security Policy headers is with a dedicated security scanner. The Vulnerability Scanner from OpDeck audits your site's security headers in seconds, including your CSP configuration.
Here's what makes it particularly useful:
It checks more than just presence. The scanner doesn't just tell you whether a CSP header exists — it analyzes the policy for common weaknesses like:
- Use of
unsafe-inlineinscript-src - Wildcard (
*) sources that defeat the purpose of CSP - Missing
object-srcdirectives (a common XSS vector via Flash or plugins) - Absence of
base-urirestrictions - Missing
form-actioncontrols
It checks all the related security headers together. CSP is part of a broader set of HTTP security headers. The scanner simultaneously checks for:
X-Frame-Options(clickjacking protection)X-Content-Type-Options(MIME sniffing protection)Strict-Transport-Security(HTTPS enforcement)Referrer-PolicyPermissions-Policy
How to use it:
- Go to the Vulnerability Scanner on OpDeck
- Enter your website URL
- Click Scan
- Review the results — each header is flagged as present, missing, or misconfigured with a clear explanation
This is especially useful if you're not comfortable parsing raw header output or if you want a shareable report for a client or security review.
Understanding CSP Directives: What Each One Controls
Once you've retrieved your CSP header, you need to know how to read it. Here's a reference for the most important directives:
Source Directives
| Directive | What It Controls |
|---|---|
default-src |
Fallback for all resource types not explicitly specified |
script-src |
JavaScript files and inline scripts |
style-src |
CSS stylesheets and inline styles |
img-src |
Images (including data URIs) |
font-src |
Web fonts |
connect-src |
Fetch, XHR, WebSocket, EventSource connections |
media-src |
Audio and video elements |
object-src |
<object>, <embed>, <applet> elements |
frame-src |
Iframes and frames |
worker-src |
Web Workers and Service Workers |
manifest-src |
Web app manifests |
Navigation and Form Directives
| Directive | What It Controls |
|---|---|
base-uri |
Restricts URLs in <base> elements |
form-action |
Restricts where forms can submit data |
frame-ancestors |
Controls which pages can embed your page in a frame |
navigate-to |
Restricts navigation targets (experimental) |
Source Values
| Value | Meaning |
|---|---|
'self' |
Same origin only |
'none' |
No sources allowed |
'unsafe-inline' |
Allows inline scripts/styles (weakens security) |
'unsafe-eval' |
Allows eval() and similar (weakens security) |
'nonce-{value}' |
Allows specific inline scripts with matching nonce |
'sha256-{hash}' |
Allows scripts matching a specific hash |
https: |
Any HTTPS source |
* |
Any source (avoid this) |
Common CSP Misconfigurations to Watch For
When you check Content Security Policy headers, these are the most frequently encountered problems:
1. Missing CSP Header Entirely
This is the most common finding. No CSP means no protection. Browsers will load any resource from any origin without restriction.
Fix: Add a CSP header at the server or CDN level. Start with a strict base and loosen as needed.
2. Using unsafe-inline in script-src
Content-Security-Policy: script-src 'self' 'unsafe-inline';
This allows any inline <script> tag to execute, which largely defeats the purpose of CSP for XSS protection. Attackers who can inject HTML can still run scripts.
Fix: Use nonces or hashes instead:
Content-Security-Policy: script-src 'self' 'nonce-{random_value}';
Then add the matching nonce to each legitimate <script> tag:
<script nonce="random_value">
// your code here
</script>
3. Wildcard in script-src
Content-Security-Policy: script-src *;
This allows scripts from any domain — functionally no protection at all.
4. Missing object-src 'none'
If object-src isn't explicitly set and default-src is permissive, browsers can load Flash and plugin content, which has historically been a major attack vector.
Fix: Always include object-src 'none' unless you specifically need plugin content.
5. Report-Only Mode Left in Production
Content-Security-Policy-Report-Only: default-src 'self';
Report-only mode is great for testing, but it doesn't actually block anything. It only sends violation reports to a configured endpoint. If you're running in report-only mode in production and forgot about it, you have zero enforcement.
6. Allowing data: URIs in script-src
Content-Security-Policy: script-src 'self' data:;
The data: scheme can be used to execute arbitrary scripts and should never appear in script-src.
How to Set CSP Headers on Different Servers
Once you've identified gaps, here's how to add or fix CSP headers on common server configurations:
Apache (.htaccess or httpd.conf)
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self';"
Nginx (nginx.conf)
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self';" always;
Node.js / Express
Using the helmet package (highly recommended):
const helmet = require('helmet');
app.use(
helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'"],
styleSrc: ["'self'"],
imgSrc: ["'self'", "data:"],
fontSrc: ["'self'"],
objectSrc: ["'none'"],
baseUri: ["'self'"],
formAction: ["'self'"],
},
})
);
Cloudflare Workers
If your site runs behind Cloudflare, you can inject headers via a Worker:
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
const response = await fetch(request);
const newHeaders = new Headers(response.headers);
newHeaders.set(
'Content-Security-Policy',
"default-src 'self'; script-src 'self'; object-src 'none';"
);
return new Response(response.body, {
status: response.status,
headers: newHeaders,
});
}
Building a Habit: Regular CSP Audits
Checking your CSP header once isn't enough. Security headers need ongoing attention because:
- Third-party scripts change — A new analytics tag or chat widget may require CSP updates
- Deployments can reset headers — Especially on platforms that regenerate server configs
- New attack techniques emerge — What was a secure policy two years ago may have known bypasses today
Set up a recurring audit schedule — monthly at minimum, weekly for high-traffic or sensitive applications. You can automate this with a cron job running the Python script from earlier, or use the Vulnerability Scanner on OpDeck as part of your regular maintenance routine.
Conclusion
Knowing how to check Content Security Policy headers is a fundamental skill for anyone responsible for web security. Whether you use browser DevTools for a quick spot-check, curl for command-line inspection, a Python script for automated auditing, or a full-featured scanner, the important thing is that you're checking — and acting on what you find.
The most common outcome when you first audit a site is discovering either a missing CSP header or one that's been weakened with unsafe-inline or wildcard sources. Both are fixable, and the fixes are well worth the effort given how much damage an XSS attack can cause.
For a fast, comprehensive audit that goes beyond just CSP headers and covers your full security header posture, try the Vulnerability Scanner at OpDeck. It gives you a clear picture of where your site stands and what needs attention — no terminal required.
Try these tools
Cache Inspector
Analyze and inspect cache headers and caching behavior of your website
AI Content Analyzer
Analyze content quality, detect AI-generated text, and get improvement suggestions
Cloudflare Detection
Check if a website is using Cloudflare and its configuration
Vulnerability Scanner
Scan WordPress and Magento sites for known vulnerabilities and security misconfigurations