Direct answer: of 25 homepages, 11 return a Content-Security-Policy and 14 do not. But none actually restricts scripts: nine set only frame-ancestors, block-all-mixed-content or upgrade-insecure-requests, and two (E13, E17) use * with 'unsafe-inline' and 'unsafe-eval' in script-src. Across all 25 sites there are no nonce, hash or strict-dynamic values, and none of 151 inline scripts carries a nonce.

This study reads homepage response headers and inline script tags only; it does not execute page scripts or test actual blocking.

25
homepages
11
send CSP
9
non-script directives only
2
broad script-src
0
actually restrict scripts
151
inline scripts

Method: response headers plus inline script tags

On 2026-11-08 between 16:41 and 16:43 each of the 25 homepages from study 4 received one GET (15-second timeout); we read Content-Security-Policy (plus Report-Only and meta forms), parsed directives and tokens, and counted inline <script> tags and their nonce attributes. Page scripts are not executed.

ItemRuleBoundary
CSP presentHeader or meta Content-Security-PolicyBrowser enforcement not tested
Actually restricts scriptsscript-src/default-src without unsafe-inline/nonce/hashNo block test
Non-script onlyOnly frame-ancestors/mixed-content/upgradeScripts are not constrained
Inline scriptA script tag without srcDynamic insertion excluded

Result: 11 CSPs, nine with non-script directives only

CSP situationSitesNote
No CSP14—
Non-script directives only9frame-ancestors, block-all-mixed-content, upgrade-insecure-requests
Broad script-src2E13, E17: * plus unsafe-inline and unsafe-eval
Actually restricts scripts0—

Nine of the 11 CSPs only address framing, mixed content or protocol upgrade, not script origins; the other two do write script-src but allow any origin with *, inline scripts with 'unsafe-inline' and string evaluation with 'unsafe-eval'. That is closer to “having a CSP” than to “restricting scripts”.

nonce/hash: zero across all 25 sites

Script allowlistSitesNote
nonce-*0—
sha256/sha384 hash0—
strict-dynamic0—
unsafe-inline (regardless of origin scope)2E13, E17

Without a nonce or hash, tightening script-src while keeping the current inline scripts is not possible: removing 'unsafe-inline' would block them. The 25 sites carry 151 inline scripts (about six each, E04 alone at 41), so the migration cost is not trivial.

What this means for acceptance

  1. Separate “has a CSP” from “restricts scripts”. Nine of 11 only set non-script directives; acceptance should name the directives, not just check for a header.
  2. Do not settle for * plus unsafe-inline. E13 and E17 allow any origin and inline execution, so XSS protection is effectively gone.
  3. Introduce nonce/hash gradually. No site uses one; start with new pages or templates, then migrate old inline scripts.
  4. Reduce inline scripts. 151 inline scripts are the main obstacle to tightening CSP; move what can be externalised into files.
  5. Add CSP to security acceptance. Check default-src/script-src, unsafe-inline/unsafe-eval, nonce/hash and Report-Only; see the homepage security-header pilot. For website acceptance, see the website development service.

Limits

  • No execution: actual browser blocking and Report-Only reporting are not tested.
  • Homepage only: other paths may use different CSPs; meta parsing covers the common form only.
  • Dynamic insertion excluded: inline scripts added by JavaScript are not in the HTML.
  • One snapshot: 2026-11-08 16:41–16:43; CDN or configuration changes alter results.
  • 25-site pilot: no industry claim.

Data and reproduction

Anonymised data: equipment-homepage-csp-2026.csv (25 rows × 13 columns: CSP presence, Report-Only, script directive, unsafe-inline, nonce/hash, inline scripts, nonce count, class, time). The repository keeps docs/research/2026-11-homepage-csp.csv.

Parser: scripts/csp_inline_probe.py; unit tests: scripts/test_content_csp_inline.py (16 tests, no network). Run:

python -m unittest scripts.test_content_csp_inline

Related: the homepage security-header pilot, the homepage blocking-resource pilot, and the homepage HTTPS certificate and TLS pilot.

Sources and definitions

  1. Sample: the 25 homepages from study 4 (same sample_id).
  2. Fetch: 2026-11-08 16:41–16:43 Asia/Shanghai, serial, 0.5 s apart, 15-second timeout.
  3. CSP: response header first, then meta; directives and tokens compared after removing quotes.
  4. Inline scripts: script tags without src; total and nonce-bearing counts.

Frequently asked questions

Does a CSP mean the page is secure?

No. Nine of the CSP sites set only frame-ancestors, block-all-mixed-content or upgrade-insecure-requests, with no script restriction.

What is wrong with * plus unsafe-inline in script-src?

It allows scripts from any origin and inline scripts to run, so XSS protection is effectively gone; unsafe-eval also permits string evaluation.

What does zero nonce/hash mean?

No site uses a nonce or hash allowlist; tightening CSP while keeping the current inline scripts usually requires template changes first.

Are 151 inline scripts a lot?

That is about six per site, with E04 alone at 41; the more inline scripts, the higher the cost of tightening script-src.

Do 25 sites represent the industry?

No. This is the same 25 equipment-company homepages from study 4; it describes only these pages.

Can the data be re-checked?

Yes. The public CSV has 25 rows by 13 columns; scripts/csp_inline_probe.py has 16 offline unit tests.

About the author

Lingyi Information Official (delivery team) works on requirements, proposals and acceptance for corporate websites, brand and smart-manufacturing projects. This article parses homepage CSP headers and inline script tags only; it does not execute scripts, verify actual blocking or reporting, and is not a security verdict on any site; the 25-site sample is a pilot.

Missing canonical is a common homepage gap

25 sites: 9 canonical, 16 missing; 8 og:url.

Request a recheck plan