Missing or Wildcard CSP script-src Directive

fix now global

The script-src directive is the most security-relevant part of any Content Security Policy. It controls which origins can deliver executable JavaScript. When script-src is missing, the browser falls back to default-src. If default-src is also absent or set to a wildcard, all script sources are permitted. A wildcard script-src (* ) explicitly allows scripts from any origin. Both conditions reduce CSP to a cosmetic header with no meaningful script restriction.

What's wrong

The Content Security Policy does not restrict script execution. This occurs in three patterns. First: the CSP has no script-src directive and default-src is either absent or set to a value that permits broad loading. The browser resolves the missing directive by falling back to default-src, and if that fallback is permissive, scripts load from anywhere. Second: script-src is present but set to * (wildcard), which explicitly permits scripts from any origin. Third: the CSP contains script-src but default-src is the only restrictive directive, and the operator assumes script-src inherits restrictions it does not. In all three cases, the browser executes scripts from untrusted origins without objection.

Why it matters

Script execution is the highest-impact capability a browser grants to external content. A script runs with the full privileges of the page: it reads cookies, captures input, modifies the DOM, and makes network requests as the user. CSP exists primarily to restrict this capability. A policy that allows unrestricted script sources provides no defense against cross-site scripting, supply chain attacks through compromised CDNs, or unauthorized third-party code. The header is present but functionally empty. Automated scanners may report CSP as configured, masking the actual exposure.

How the fallback chain works

CSP directive resolution follows a specific precedence. When the browser evaluates whether a script should execute, it first checks for script-src. If script-src is not present in the policy, the browser falls back to default-src. If default-src is also absent, the browser permits the resource. This means a CSP like default-src 'self'; style-src 'self' has no script-src directive and no usable fallback — the browser permits scripts from any origin. The operator may believe default-src covers scripts, but only when default-src is explicitly set. A CSP that restricts images, styles, and fonts but omits script-src provides granular control over low-risk resources while leaving the highest-risk resource unrestricted.

The correct change

Add an explicit script-src directive that names the specific origins permitted to deliver JavaScript. At minimum, script-src should be set to 'self' to restrict scripts to the same origin. If third-party scripts are required, list each origin individually. Remove wildcard values. Do not rely on default-src as the sole control for script execution. An explicit script-src makes intent legible: the operator has decided which origins can execute code, and the browser enforces that decision.

Scope

This condition applies globally. CSP is delivered via HTTP response header or meta tag and governs the entire document. Every script element, external script reference, and dynamic script injection is subject to the script-src directive. A missing or wildcard script-src affects all pages sharing the same CSP configuration.

How to verify

  • · Validation confirms the condition is resolved:
  • · • Content-Security-Policy header contains an explicit script-src directive
  • · • script-src does not include * (wildcard)
  • · • script-src lists specific trusted origins rather than broad patterns
  • · • default-src alone is not relied upon to restrict script execution
  • · • Browser developer tools show script-src in parsed CSP
  • · • Attempting to load a script from an unlisted origin triggers a CSP violation
  • · • CSP violation reports confirm enforcement is active

Takeaway

  • · script-src is the most consequential directive in any Content Security Policy
  • · Missing script-src falls back to default-src; if default-src is absent or permissive, scripts are unrestricted
  • · Wildcard script-src explicitly permits scripts from any origin, defeating CSP entirely
  • · Explicit script-src with named origins is the minimum effective configuration

FAQ

If default-src is set to 'self', does that cover scripts?

Yes, but only when script-src is absent. If default-src is 'self' and no script-src exists, scripts are restricted to the same origin. However, this is implicit. Adding an explicit script-src makes intent clear and allows script-specific restrictions like nonces without affecting other resource types.

Why is a wildcard script-src worse than no CSP at all?

Functionally they are equivalent. Both allow scripts from any origin. But a wildcard script-src is arguably worse because it creates a false signal. The CSP header exists, automated tools may report it as configured, and operators may believe scripts are restricted when they are not.

Can script-src and default-src coexist?

Yes. When both are present, script-src takes precedence for script resources. default-src serves as a fallback only for directives not explicitly defined. A common pattern is default-src 'none'; script-src 'self' — this blocks all resources by default and selectively permits same-origin scripts.

What if I need scripts from many third-party origins?

List each origin explicitly. A long script-src is preferable to a wildcard. Each listed origin represents a deliberate trust decision. If the list becomes unmanageable, it signals a dependency problem worth addressing separately. Wildcards hide the true scope of trust.

Does this affect inline scripts?

Inline script handling is controlled by 'unsafe-inline', nonces, and hashes within the script-src directive. A missing script-src that falls back to a permissive default-src also permits inline scripts by default. An explicit script-src without 'unsafe-inline' blocks inline scripts, which is the intended behavior for XSS prevention.

How do I audit what scripts currently load on my pages?

Deploy a report-only CSP with a restrictive script-src and a reporting endpoint. The browser logs every script that would violate the policy without blocking it. Review the reports to build a list of actual script origins. Use that list to construct an enforcing script-src that reflects real dependencies.

The fix

Intent: Restrict script execution to explicitly trusted origins via an explicit script-src directive

End state: Content Security Policy includes a script-src directive that names specific allowed origins, with no wildcards, and does not rely solely on default-src for script restriction

  • Do not use wildcard (*) in script-src
  • Do not rely on default-src alone to restrict script execution
  • Do not assume CSP presence means scripts are restricted without verifying script-src
  • Do not add data: or blob: to script-src without understanding the XSS implications