Content-Security-Policy Auditor avatar

Content-Security-Policy Auditor

Pricing

Pay per usage

Go to Apify Store
Content-Security-Policy Auditor

Content-Security-Policy Auditor

Deeply audit a public URL's Content-Security-Policy and Content-Security-Policy-Report-Only headers. Parses directives and sources, flags unsafe-inline, unsafe-eval, non-HTTPS sources, wildcards, missing default-src and frame-ancestors, nonces, hashes, and deprecated directives.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Sanskar Jaiswal

Sanskar Jaiswal

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

19 hours ago

Last modified

Share

Fetches one public URL and deeply audits its Content-Security-Policy and Content-Security-Policy-Report-Only response headers. Parses every directive and source, flags unsafe-inline, unsafe-eval, non-HTTPS sources, wildcards, missing default-src and frame-ancestors, nonces and hashes, deprecated directives (report-uri, plugin-types, prefetch-src, child-src), and duplicate directives. Returns a readiness score, letter grade, issues, and recommendations. Built for security teams, devops engineers, frontend platform teams, site migration QA, and agency consultants.

Use cases

  • Verify a deployed CSP blocks inline scripts and eval after a release or cutover.
  • Detect unsafe inline/eval or wildcard sources that weaken XSS protection before a launch.
  • Catch missing default-src or frame-ancestors so per-directive coverage gaps and clickjacking are visible.
  • Spot deprecated directives (report-uri, plugin-types, prefetch-src, child-src) and migrate to the Reporting API and frame-src/worker-src.
  • Find duplicate directives that silently shadow each other (only the first is applied).
  • Run scheduled checks on critical origins to catch CSP configuration drift on edge servers.
  • Feed structured results into security QA dashboards or CI pipelines.

Input

FieldTypeDescription
startUrlstringPublic HTTP or HTTPS URL to audit. URLs with credentials and private network targets are rejected.
timeoutSecondsintegerRequest timeout from 3 to 30 seconds. Defaults to 10.

Output

The actor pushes one dataset item per run.

FieldTypeDescription
inputUrlstringOriginal URL from input.
normalizedInputUrlstringNormalized input URL after defaulting the scheme.
finalUrlstringFinal page URL after redirects.
httpsbooleanTrue when the final URL is HTTPS.
okbooleanTrue when the fetch succeeded.
checkedAtstringISO timestamp for the audit.
httpStatusinteger or nullHTTP status code from the response.
hasCspbooleanTrue when a Content-Security-Policy header is present.
hasReportOnlybooleanTrue when a Content-Security-Policy-Report-Only header is present.
rawCspstring or nullRaw Content-Security-Policy header value.
rawReportOnlystring or nullRaw Content-Security-Policy-Report-Only header value.
reportingEndpointsstring or nullReporting-Endpoints header value, if present.
reportTostring or nullReport-To header value, if present (deprecated).
directivesarrayParsed CSP directives, each with name, sources, audit flags, and per-directive issues.
directiveCountintegerNumber of parsed directives.
sourceCountintegerTotal number of source expressions across all directives.
unsafeInlinebooleanTrue when any directive contains 'unsafe-inline'.
unsafeEvalbooleanTrue when any directive contains 'unsafe-eval'.
unsafeHashesbooleanTrue when any directive contains 'unsafe-hashes'.
hasWildcardSourcebooleanTrue when a fetch directive uses a wildcard host or *.
hasNonHttpsSourcebooleanTrue when a fetch directive lists an http:// URL or the http: scheme source.
hasDefaultSrcbooleanTrue when default-src is present.
hasFrameAncestorsbooleanTrue when frame-ancestors is present.
hasNoncebooleanTrue when a 'nonce-...' source is present.
hasHashbooleanTrue when a 'sha256-...', 'sha384-...', or 'sha512-...' source is present.
deprecatedDirectivesarrayList of deprecated directive names found (report-uri, plugin-types, prefetch-src, child-src).
deprecatedDirectiveCountintegerNumber of deprecated directives found.
duplicateDirectivesarrayList of directive names that appear more than once.
duplicateDirectiveCountintegerNumber of duplicate directive names.
scoreintegerCSP readiness score from 0 to 100.
gradestringLetter grade from A+ to F.
issuesarrayHuman-readable issues with directive and severity where applicable.
recommendationsarraySuggested fixes.
errorstring or nullFetch-level error, if the request failed.

Example input

{
"startUrl": "https://example.com/",
"timeoutSeconds": 10
}

Example output

{
"inputUrl": "https://example.com/",
"normalizedInputUrl": "https://example.com/",
"finalUrl": "https://example.com/",
"https": true,
"ok": true,
"checkedAt": "2025-01-01T00:00:00.000Z",
"httpStatus": 200,
"hasCsp": true,
"hasReportOnly": false,
"rawCsp": "default-src 'none'; script-src 'self' 'nonce-abc123='; frame-ancestors 'none'",
"rawReportOnly": null,
"reportingEndpoints": null,
"reportTo": null,
"directives": [
{
"name": "default-src",
"sources": ["'none'"],
"isFetchDirective": true,
"isDeprecated": false,
"keywords": ["'none'"],
"unsafeInline": false,
"unsafeEval": false,
"unsafeHashes": false,
"hasNonce": false,
"hasHash": false,
"hasWildcard": false,
"hasNonHttps": false,
"nonHttpsSources": [],
"wildcardSources": [],
"issues": []
},
{
"name": "script-src",
"sources": ["'self'", "'nonce-abc123='"],
"isFetchDirective": true,
"isDeprecated": false,
"keywords": ["'self'"],
"unsafeInline": false,
"unsafeEval": false,
"unsafeHashes": false,
"hasNonce": true,
"hasHash": false,
"hasWildcard": false,
"hasNonHttps": false,
"nonHttpsSources": [],
"wildcardSources": [],
"issues": []
},
{
"name": "frame-ancestors",
"sources": ["'none'"],
"isFetchDirective": true,
"isDeprecated": false,
"keywords": ["'none'"],
"unsafeInline": false,
"unsafeEval": false,
"unsafeHashes": false,
"hasNonce": false,
"hasHash": false,
"hasWildcard": false,
"hasNonHttps": false,
"nonHttpsSources": [],
"wildcardSources": [],
"issues": []
}
],
"directiveCount": 3,
"sourceCount": 5,
"unsafeInline": false,
"unsafeEval": false,
"unsafeHashes": false,
"hasWildcardSource": false,
"hasNonHttpsSource": false,
"hasDefaultSrc": true,
"hasFrameAncestors": true,
"hasNonce": true,
"hasHash": false,
"deprecatedDirectives": [],
"deprecatedDirectiveCount": 0,
"duplicateDirectives": [],
"duplicateDirectiveCount": 0,
"score": 100,
"grade": "A+",
"issues": [],
"recommendations": [
"CSP posture looks strong; consider load-testing with report-only changes and monitor CSP reports."
],
"error": null
}

Security

  • Only public HTTP and HTTPS URLs are fetched.
  • URLs with usernames or passwords are rejected.
  • Private IPv4, private IPv6, localhost, link-local, and private DNS resolutions are blocked before fetching.
  • Redirect destinations are revalidated before they are followed.
  • The actor does not require logins, cookies, browser sessions, or credentials.
  • The actor fetches headers only; it does not fetch any URLs referenced inside the CSP.

Pricing

EventSuggested price
Actor start$0.005
URL audited$0.01

Suggested launch price: about $0.015 per audited URL. Teams can schedule the actor for recurring checks on important origins after deploys and CDN cutovers.

FAQ

Does this actor crawl multiple URLs or a whole site?

No. It fetches one URL per run. This keeps runs cheap and predictable for CI and scheduled monitoring.

How does the score work?

The score starts at 100 and is reduced for: unsafe-inline (-25), unsafe-eval (-20), unsafe-hashes (-10), wildcard sources (-15), non-HTTPS sources (-10), missing frame-ancestors (-5), deprecated directives (-3 each, capped at -10), and duplicate directives (-4 each, capped at -8). A modern nonce/hash posture without unsafe-inline adds +5 (capped at 100). Policies that enforce nothing (Content-Security-Policy absent) receive an F.

Why does this actor check Content-Security-Policy-Report-Only separately?

Content-Security-Policy-Report-Only is intentionally advisory; browsers report violations without blocking. The actor parses it and surfaces structural issues (missing default-src, unsafe keywords, wildcards) but the readiness score is computed from the enforced Content-Security-Policy when present.

Which directives are considered deprecated?

report-uri (replaced by the Reporting API and Reporting-Endpoints), plugin-types (removed in CSP3, replaced by X-Content-Type-Options), prefetch-src (removed in CSP3), and child-src (deprecated in favor of frame-src and worker-src).

How are duplicate directives handled?

When a directive name appears more than once in the same policy, the actor reports each duplicate name. Browsers apply only the first declaration and silently ignore the rest, so duplicates usually indicate a configuration mistake.

What is the difference between this actor and the HTTP Security Headers Auditor?

The HTTP Security Headers Auditor checks ten security response headers at a high level and treats CSP as one of them. This Content-Security-Policy Auditor is specialized: it parses every CSP directive and source, evaluates fetch-directive coverage, classifies unsafe keywords, non-HTTPS sources, wildcards, nonces, hashes, deprecated directives, and duplicates, and returns a recommended hardening path for CSP specifically.