Skip to content

Policy Scoring

CSP Analyser scores your generated policy on a 0-100 scale against established CSP best practices. The score starts at 100 and is adjusted by deductions (for dangerous patterns) and bonuses (for security best practices).

Grade boundaries

GradeScore rangeMeaning
A90-100Excellent. Follows best practices with no critical issues.
B75-89Good. Minor improvements possible.
C55-74Fair. Some significant security gaps.
D35-54Poor. Multiple security issues need attention.
F0-34Failing. Critical security problems.

Scoring rubric

Critical deductions

FindingPointsCondition
'unsafe-eval' in script directives-30script-src, script-src-elem, or script-src-attr contains 'unsafe-eval'
'unsafe-eval' in default-src-30default-src contains 'unsafe-eval' and no explicit script-src overrides it
Wildcard * in critical directives-25default-src, script-src, or script-src-elem contains *

Warning deductions

FindingPointsCondition
'unsafe-inline' in script directives-20script-src, script-src-elem, or script-src-attr contains 'unsafe-inline'
'unsafe-inline' in default-src-20default-src contains 'unsafe-inline' and no explicit script-src overrides it
data: in script directives-20script-src, script-src-elem, or script-src-attr contains data:
Missing default-src-15Policy does not declare default-src
Wildcard * in other directives-10Any non-critical directive contains *

Info deductions

FindingPointsCondition
Missing object-src-5No object-src declared and default-src is not 'none'
Missing base-uri-5No base-uri declared
Missing form-action-5No form-action declared

Positive bonuses

FindingPointsCondition
Nonces or hashes+10Any directive uses 'nonce-...', 'sha256-...', 'sha384-...', or 'sha512-...'
'strict-dynamic'+5script-src, script-src-elem, script-src-attr, or default-src contains 'strict-dynamic'
Violation reporting+5report-uri or report-to directive is present

Example output

CSP Score: 80/100 (Grade: B)

Issues:
  [!] 'unsafe-inline' allows inline script execution (XSS risk) (-20 pts)

Strengths:
  [+] Violation reporting is configured (+5 pts)

Findings are sorted by severity (most impactful first). The icons indicate severity:

  • !! = critical
  • ! = warning
  • ? = info
  • + = positive

Common findings and how to fix them

'unsafe-eval' allows arbitrary code execution

Impact: Critical (-30 points)

Your site or a dependency uses eval(), new Function(), or similar dynamic code execution. This is one of the most dangerous CSP bypasses.

Unlike 'unsafe-inline', CSP has no hash or nonce equivalent for 'unsafe-eval' — the only way to eliminate it is to find and remove the eval() calls.

How to fix:

  1. Identify the source using the violation details (sourceFile, lineNumber)
  2. Refactor the code to avoid eval(). Most uses can be replaced with JSON parsing, template literals, or static function references.
  3. If a third-party library requires it and cannot be replaced, isolate it in a sandboxed iframe with its own restrictive policy
  4. To deploy a strict policy while you're fixing the remaining call sites, run with --strip-unsafe-eval. This removes 'unsafe-eval' from the generated policy. Deploy it in report-only mode (--report-only) first, then promote to enforcing once the remaining violations have been addressed.

Common culprits:

PatternReplacement
eval(jsonString)JSON.parse(jsonString)
new Function('return ' + expr)()Lookup table or switch statement
setTimeout("fn()", 100)setTimeout(fn, 100) (pass reference, not string)
Vue runtime compiler (template: "...")Build-time compilation via single-file components
Older AngularJS $eval/$parseEnable strict DI and avoid these with untrusted input
Webpack dev eval sourcemapsUse devtool: 'source-map' instead of eval or eval-source-map

'unsafe-inline' allows inline script execution

Impact: Warning (-20 points)

Inline <script> tags or inline event handlers (onclick, onload) are in use. This is the primary XSS attack vector that CSP is designed to prevent.

How to fix:

  1. Move inline scripts to external .js files
  2. Use hashes: run with --hash to automatically replace 'unsafe-inline' with SHA-256 hashes computed from full inline content (scripts, styles, event handlers, and style attributes)
  3. Use nonces: run with --nonce to replace 'unsafe-inline' with nonce placeholders (requires runtime nonce injection on your server)
  4. Remove inline event handlers and use addEventListener() instead

Missing object-src

Impact: Info (-5 points)

Without object-src, the default-src fallback applies to <object>, <embed>, and <applet> elements. If default-src is not 'none', plugins could be loaded.

How to fix: Most modern sites do not use plugins. Add object-src 'none' to your policy. CSP Analyser generates this automatically at the strict level.

Missing base-uri

Impact: Info (-5 points)

Without base-uri, an attacker who can inject HTML could add a <base> tag to redirect all relative URLs.

How to fix: Add base-uri 'self' to your policy.

Usage

bash
csp-analyser score <session-id>
csp-analyser score <session-id> --strictness strict
json
{
  "tool": "score_policy",
  "sessionId": "...",
  "strictness": "strict"
}

TIP

Re-score with --strictness strict to see how much your score improves with tighter source expressions. Wildcards in non-critical directives cost -10 points each.


Released under the MIT License.