@blamejs/exceptd-skills 0.16.12 → 0.16.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,646 @@
1
+ {
2
+ "_meta": {
3
+ "id": "network-trust",
4
+ "version": "1.0.0",
5
+ "last_threat_review": "2026-06-02",
6
+ "threat_currency_score": 93,
7
+ "changelog": [
8
+ {
9
+ "version": "1.0.0",
10
+ "date": "2026-06-02",
11
+ "summary": "Initial seven-phase network-layer trust (AiTM-resistance) playbook. Covers the trust-anchor checks below the application that TLS alone does not provide: DNSSEC validation, DANE/TLSA certificate pinning on capable peers, TSIG on zone operations, mTLS private-CA pinning, RFC 9421 HTTP message-signature verification, DNS-rebinding/SSRF guarding, authenticated time (NTS vs unauthenticated NTP) and its effect on certificate-validity windows and TOTP, and Public-Suffix-List currency for cookie/domain boundaries. Maps to the DNSSEC resolver-DoS catalog entries (KeyTrap CVE-2023-50387, NSEC3 CVE-2023-50868) for the validation surface. Distinct from crypto / post-quantum-migration (primitive strength) — this is trust-anchor VALIDATION, not algorithm choice. Closes the GRC loop against NIST 800-53 SC-8 / SC-20, ISO 27001 A.8.21, NIS2 Art.21, and UK-CAF B4."
12
+ }
13
+ ],
14
+ "owner": "@blamejs/platform-security",
15
+ "air_gap_mode": false,
16
+ "scope": "service",
17
+ "preconditions": [
18
+ {
19
+ "id": "network-config-or-source-read",
20
+ "description": "Agent must read the operator's network-layer source and/or runtime configuration to inspect DNS resolution, DANE/TSIG, time synchronisation, mTLS trust, and request-signature verification. A host with neither marks the playbook visibility_gap=no_network_trust_inventory.",
21
+ "check": "agent_has_filesystem_read == true OR agent_has_network_config == true",
22
+ "on_fail": "halt"
23
+ }
24
+ ],
25
+ "mutex": [],
26
+ "feeds_into": [
27
+ {
28
+ "playbook_id": "crypto",
29
+ "condition": "finding.includes_tls_primitive_weakness == true"
30
+ },
31
+ {
32
+ "playbook_id": "framework",
33
+ "condition": "analyze.compliance_theater_check.verdict == 'theater'"
34
+ }
35
+ ]
36
+ },
37
+ "domain": {
38
+ "name": "Network-layer trust (AiTM-resistance: DNS / TLS-pinning / time)",
39
+ "attack_class": "cloud-misconfig",
40
+ "atlas_refs": [],
41
+ "attack_refs": [
42
+ "T1557",
43
+ "T1071.004",
44
+ "T1556"
45
+ ],
46
+ "cve_refs": [
47
+ "CVE-2023-50387",
48
+ "CVE-2023-50868"
49
+ ],
50
+ "cwe_refs": [
51
+ "CWE-345",
52
+ "CWE-918",
53
+ "CWE-290",
54
+ "CWE-347"
55
+ ],
56
+ "frameworks_in_scope": [
57
+ "nist-800-53",
58
+ "iso-27001-2022",
59
+ "nis2",
60
+ "uk-caf"
61
+ ]
62
+ },
63
+ "phases": {
64
+ "govern": {
65
+ "jurisdiction_obligations": [
66
+ {
67
+ "jurisdiction": "EU",
68
+ "regulation": "NIS2 Art.23",
69
+ "obligation": "notify_regulator",
70
+ "window_hours": 24,
71
+ "clock_starts": "detect_confirmed",
72
+ "evidence_required": [
73
+ "network_trust_inventory",
74
+ "aitm_or_dns_forgery_evidence"
75
+ ]
76
+ },
77
+ {
78
+ "jurisdiction": "EU",
79
+ "regulation": "eIDAS Art.19",
80
+ "obligation": "notify_supervisory_body",
81
+ "window_hours": 24,
82
+ "clock_starts": "detect_confirmed",
83
+ "evidence_required": [
84
+ "affected_trust_service",
85
+ "time_or_cert_trust_impact"
86
+ ]
87
+ }
88
+ ],
89
+ "theater_fingerprints": [
90
+ {
91
+ "pattern_id": "tls-equals-authenticated-peer",
92
+ "claim": "We use TLS everywhere, so the peer is authenticated.",
93
+ "fast_detection_test": "TLS authenticates against a CA bundle, not the EXPECTED peer. Ask whether DANE/TLSA (server-to-server) or a pinned private CA (mTLS) confirms the specific peer key — web-PKI alone admits any mis-issued cert."
94
+ },
95
+ {
96
+ "pattern_id": "validating-resolver-somewhere",
97
+ "claim": "We use a DNSSEC-validating resolver.",
98
+ "fast_detection_test": "Confirm the APPLICATION path trusts the AD flag (or validates) end-to-end. A validating resolver upstream is moot if the app accepts any answer over an unauthenticated hop."
99
+ },
100
+ {
101
+ "pattern_id": "time-is-just-ntp",
102
+ "claim": "Time sync is handled (NTP).",
103
+ "fast_detection_test": "Unauthenticated NTP is attacker-steerable. Ask whether NTS or an authenticated source is used, and whether cert-validity / TOTP depend on that clock."
104
+ }
105
+ ],
106
+ "framework_context": {
107
+ "gap_summary": "Org network controls equate TLS with peer authenticity and assume DNS and time are trustworthy. None require the trust-anchor VALIDATION layer — DNSSEC, DANE/TLSA, TSIG, mTLS pinning, authenticated time — that adversary-in-the-middle attacks exploit beneath TLS.",
108
+ "lag_score": 71,
109
+ "per_framework_gaps": [
110
+ {
111
+ "framework": "nist-800-53",
112
+ "control_id": "SC-20",
113
+ "designed_for": "secure name/address resolution",
114
+ "insufficient_because": "commonly attested by \"we use a validating resolver\" without confirming the application path validates/trusts DNSSEC end-to-end."
115
+ },
116
+ {
117
+ "framework": "nist-800-53",
118
+ "control_id": "SC-8",
119
+ "designed_for": "transmission confidentiality and integrity",
120
+ "insufficient_because": "satisfied by TLS to a CA bundle; does not require DANE pinning, DNSSEC, or authenticated time, so a valid-but-wrong cert or forged DNS answer passes."
121
+ }
122
+ ]
123
+ },
124
+ "skill_preload": [
125
+ "network-trust",
126
+ "pqc-first",
127
+ "identity-assurance",
128
+ "framework-gap-analysis",
129
+ "compliance-theater",
130
+ "policy-exception-gen"
131
+ ]
132
+ },
133
+ "direct": {
134
+ "threat_context": "Below the application, TLS authenticates a certificate against a CA bundle — not the specific peer you intend to reach, and not the DNS answer or clock that got you there. Adversary-in-the-middle attacks exploit the missing trust-anchor validation: forge a DNS answer (no DNSSEC), present a mis-issued-but-valid cert (no DANE/TLSA or CA pin), shift the clock (no NTS) to revive an expired cert or TOTP window, or rebind a name to an internal address. These are validation-posture gaps, not primitive-strength issues.",
135
+ "rwep_threshold": {
136
+ "escalate": 55,
137
+ "monitor": 35,
138
+ "close": 20
139
+ },
140
+ "framework_lag_declaration": "A clean TLS / \"validating resolver\" / NTP audit is NON-EVIDENCE for network-trust posture; it confirms encryption and a CA bundle, not end-to-end DNSSEC validation, DANE/TLSA or mTLS pinning, or authenticated time.",
141
+ "skill_chain": [
142
+ {
143
+ "skill": "network-trust",
144
+ "purpose": "enumerate the DNS / DANE / TSIG / time / mTLS / message-signature trust checks"
145
+ },
146
+ {
147
+ "skill": "pqc-first",
148
+ "purpose": "cross-check the transport crypto posture the trust layer sits on"
149
+ },
150
+ {
151
+ "skill": "compliance-theater",
152
+ "purpose": "separate \"we use TLS / a validating resolver / NTP\" claims from enforced trust validation"
153
+ },
154
+ {
155
+ "skill": "framework-gap-analysis",
156
+ "purpose": "map findings to the SC-8 / SC-20 / Art.21 gaps the controls do not cover"
157
+ }
158
+ ],
159
+ "token_budget": {
160
+ "estimated_total": 13000,
161
+ "breakdown": {
162
+ "govern": 1200,
163
+ "direct": 800,
164
+ "look": 4500,
165
+ "detect": 4000,
166
+ "analyze": 1800,
167
+ "validate": 500,
168
+ "close": 200
169
+ }
170
+ }
171
+ },
172
+ "look": {
173
+ "artifacts": [
174
+ {
175
+ "id": "dns-trust-config",
176
+ "type": "config_file",
177
+ "source": "grep for network-dnssec / network-dns-resolver / network-dns / safe-dns / AD flag / DNSSEC / DoT / DoH across the resolver path and config.",
178
+ "description": "Whether the resolver validates DNSSEC (or trusts a validated upstream over an authenticated channel) and how it handles private-range answers.",
179
+ "required": true,
180
+ "air_gap_alternative": "Inspect the resolver source for DNSSEC validation / AD-flag trust and the rebinding guard."
181
+ },
182
+ {
183
+ "id": "dane-tsig-config",
184
+ "type": "config_file",
185
+ "source": "grep for network-dane / TLSA / network-tsig / AXFR / IXFR / zone transfer / dynamic update across the network layer.",
186
+ "description": "Whether outbound TLS checks DANE/TLSA on capable peers and whether zone operations require TSIG.",
187
+ "required": false,
188
+ "air_gap_alternative": "Inspect the DANE and TSIG modules for enforcement; if no authoritative zones exist, TSIG is not-in-scope."
189
+ },
190
+ {
191
+ "id": "time-trust-config",
192
+ "type": "config_file",
193
+ "source": "grep for network-nts / ntp-check / NTS / time source / clock across the time-sync path.",
194
+ "description": "Whether time is synchronised over authenticated NTS or an authenticated source, vs unauthenticated NTP.",
195
+ "required": true,
196
+ "air_gap_alternative": "Inspect the time-sync config for NTS / authenticated source."
197
+ },
198
+ {
199
+ "id": "mtls-trust-config",
200
+ "type": "config_file",
201
+ "source": "grep for mtls-ca / mtls-engine / ca bundle / pin / SPKI / verify client cert across the mTLS engine.",
202
+ "description": "Whether mTLS pins the expected private CA / SPKI vs trusting a broad public CA bundle.",
203
+ "required": false,
204
+ "air_gap_alternative": "Inspect the mTLS engine for the trust-anchor / CA-pin configuration."
205
+ },
206
+ {
207
+ "id": "message-signature-and-psl-config",
208
+ "type": "config_file",
209
+ "source": "grep for http-message-signature / RFC 9421 / Signature-Input / content-digest / public-suffix across the inbound request path and cookie layer.",
210
+ "description": "Whether inbound HTTP message signatures are verified with adequate covered-components, and whether the PSL is current.",
211
+ "required": false,
212
+ "air_gap_alternative": "Inspect the request-verify path for signature verification + covered-components, and the PSL currency."
213
+ }
214
+ ],
215
+ "collection_scope": {
216
+ "time_window": "current network-layer configuration + source state (point-in-time posture audit)",
217
+ "asset_scope": "every service whose security depends on DNS authenticity, peer-certificate identity, accurate time, or request-signature integrity"
218
+ },
219
+ "environment_assumptions": [
220
+ {
221
+ "assumption": "The service makes outbound connections and/or resolves names whose authenticity matters.",
222
+ "if_false": "A fully air-gapped service with fixed pinned IPs and no name resolution has a reduced surface; restrict to the time-trust and message-signature indicators."
223
+ },
224
+ {
225
+ "assumption": "Network-layer source or config is readable.",
226
+ "if_false": "Mark visibility_gap=no_network_trust_inventory and report only what the resolver/transport source reveals."
227
+ }
228
+ ],
229
+ "fallback_if_unavailable": [
230
+ {
231
+ "artifact_id": "dane-tsig-config",
232
+ "fallback_action": "If the operator is not authoritative for any DNS zone and does not run an MTA, skip the TSIG and DANE indicators.",
233
+ "confidence_impact": "none"
234
+ },
235
+ {
236
+ "artifact_id": "mtls-trust-config",
237
+ "fallback_action": "If no mTLS is used, skip the CA-pinning indicator.",
238
+ "confidence_impact": "none"
239
+ }
240
+ ]
241
+ },
242
+ "detect": {
243
+ "indicators": [
244
+ {
245
+ "id": "dnssec-validation-not-enforced",
246
+ "type": "config_value",
247
+ "value": "The resolver path does not validate DNSSEC — it does not require/trust the AD (Authenticated Data) flag from a validating resolver and does not validate DS/DNSKEY/RRSIG itself, so unsigned or forged answers are accepted as authentic.",
248
+ "description": "Without DNSSEC validation an on-path or cache-poisoning attacker forges DNS answers (e.g. redirecting an MX, an OCSP endpoint, or an issuer host) and the application trusts them — the foundation of many AiTM chains.",
249
+ "confidence": "high",
250
+ "deterministic": false,
251
+ "attack_ref": "T1071.004",
252
+ "false_positive_checks_required": [
253
+ "A stub resolver that trusts a validated AD flag from a DNSSEC-validating upstream over an authenticated channel (e.g. DoT/DoH to a trusted resolver) is safe; the finding is a path that neither validates locally nor trusts a validated upstream.",
254
+ "Names in non-DNSSEC-signed zones cannot be validated regardless; the finding is the resolver ignoring DNSSEC where the zone IS signed (or not preferring signed answers)."
255
+ ]
256
+ },
257
+ {
258
+ "id": "dane-tlsa-not-checked",
259
+ "type": "config_value",
260
+ "value": "Outbound TLS to peers that publish DANE/TLSA records (notably MTA-to-MTA SMTP, and any DANE-pinned service) does not check TLSA, relying only on web-PKI CA trust.",
261
+ "description": "Web-PKI alone lets any CA-issued (or mis-issued) certificate pass; DANE/TLSA pins the expected key via DNSSEC. Skipping it leaves an AiTM with a valid-but-wrong cert undetected on DANE-capable peers.",
262
+ "confidence": "medium",
263
+ "deterministic": false,
264
+ "attack_ref": "T1557",
265
+ "false_positive_checks_required": [
266
+ "DANE applies where the peer publishes TLSA AND the resolver validates DNSSEC; a peer with no TLSA record is web-PKI-only and not this finding.",
267
+ "For browser-facing HTTPS (no DANE adoption) this indicator is not-in-scope; it targets MTA-STS/DANE-capable server-to-server TLS."
268
+ ]
269
+ },
270
+ {
271
+ "id": "unauthenticated-ntp-no-nts",
272
+ "type": "config_value",
273
+ "value": "Time is synchronised over unauthenticated NTP (no NTS / Network Time Security), so a network attacker can shift the host clock.",
274
+ "description": "A shifted clock revives expired/revoked certificates (validity windows), shifts TOTP/HOTP windows (auth bypass), and breaks short-lived-token and Kerberos assumptions — time is a silent trust input.",
275
+ "confidence": "medium",
276
+ "deterministic": false,
277
+ "attack_ref": "T1557",
278
+ "false_positive_checks_required": [
279
+ "A host with an authenticated time source (NTS, a GPS/PTP appliance, or an authenticated internal time service) is safe; the finding is network-NTP-only with no authentication.",
280
+ "A host whose clock is hardware-disciplined and never network-steered is not exposed to NTP time-shift."
281
+ ]
282
+ },
283
+ {
284
+ "id": "tsig-absent-on-zone-operations",
285
+ "type": "config_value",
286
+ "value": "DNS zone transfers (AXFR/IXFR) or dynamic updates are served/accepted without TSIG (or SIG(0)) authentication.",
287
+ "description": "Unauthenticated AXFR leaks the full zone (recon); unauthenticated dynamic update lets an attacker inject or overwrite records, hijacking name resolution for the zone.",
288
+ "confidence": "medium",
289
+ "deterministic": false,
290
+ "attack_ref": "T1071.004",
291
+ "false_positive_checks_required": [
292
+ "A nameserver that restricts AXFR to TSIG-keyed secondaries (or to no external peers at all) is safe; the finding is AXFR/update reachable without TSIG.",
293
+ "A host that is not authoritative for any zone (pure resolver) has no zone-transfer surface — not-in-scope."
294
+ ]
295
+ },
296
+ {
297
+ "id": "mtls-ca-not-pinned",
298
+ "type": "config_value",
299
+ "value": "The mTLS engine accepts any certificate chaining to a broad/public CA bundle instead of pinning the specific internal/private CA (or SPKI) expected for the peer.",
300
+ "description": "A broad trust bundle means any certificate from any trusted CA authenticates as the peer; an attacker with a cert from any bundled CA impersonates the service in a mesh.",
301
+ "confidence": "medium",
302
+ "deterministic": false,
303
+ "attack_ref": "T1557",
304
+ "false_positive_checks_required": [
305
+ "A service mesh / internal mTLS that pins the private issuing CA (or peer SPKI) is safe; the finding is mTLS validating against the full public CA bundle where a private CA is expected.",
306
+ "A genuinely public-client mTLS scenario (many independent client CAs by design) is not this finding — confirm the expected trust scope."
307
+ ]
308
+ },
309
+ {
310
+ "id": "http-message-signature-not-verified",
311
+ "type": "config_value",
312
+ "value": "Inbound requests carrying an HTTP Message Signature (RFC 9421) are accepted without verifying the signature, or the signature does not cover the security-critical components (method, target-URI, content-digest, created/expires).",
313
+ "description": "An unverified or under-scoped message signature provides no integrity/authenticity guarantee — a tampered or replayed request passes as signed.",
314
+ "confidence": "medium",
315
+ "deterministic": false,
316
+ "attack_ref": "T1556",
317
+ "false_positive_checks_required": [
318
+ "Confirm the verifier checks the signature AND that the covered-components include method, @target-uri, content-digest, and a created/expires window — a verifier that accepts unsigned, or whose signature omits the body digest, is the finding.",
319
+ "An endpoint that does not use message signatures at all (relies on mTLS / bearer tokens) is not this finding."
320
+ ]
321
+ },
322
+ {
323
+ "id": "dns-rebinding-unguarded",
324
+ "type": "config_value",
325
+ "value": "Outbound/SSRF-relevant DNS resolution is not guarded against rebinding — the resolved address is re-resolved between the security check and the connection, or a name resolving to a private/link-local/loopback address is followed.",
326
+ "description": "DNS rebinding lets a name that first resolves to a public address re-resolve to an internal one, turning an allowlist check into an SSRF into internal services.",
327
+ "confidence": "medium",
328
+ "deterministic": false,
329
+ "attack_ref": "T1557",
330
+ "false_positive_checks_required": [
331
+ "A resolver that pins the checked IP for the lifetime of the connection AND refuses private/link-local/loopback/metadata addresses is safe; the finding is re-resolution or unfiltered private-range answers.",
332
+ "A client that only ever connects to a fixed pinned IP (no name re-resolution) is not exposed to rebinding."
333
+ ]
334
+ },
335
+ {
336
+ "id": "public-suffix-list-stale",
337
+ "type": "config_value",
338
+ "value": "The Public Suffix List used for cookie-scope and same-site/domain-boundary decisions is stale or absent, so the registrable-domain boundary is computed incorrectly.",
339
+ "description": "A wrong PSL boundary lets a cookie be set or read across an organizational boundary (super-cookie / cross-tenant session scoping), weakening the same-origin trust the auth layer assumes.",
340
+ "confidence": "low",
341
+ "deterministic": false,
342
+ "attack_ref": "T1556",
343
+ "false_positive_checks_required": [
344
+ "A PSL refreshed within its currency window (or pinned to a recent vendored copy with a refresh job) is safe; the finding is a years-stale or absent PSL driving cookie/domain decisions.",
345
+ "A service that does not make registrable-domain decisions (single fixed host, no wildcard cookies) is not exposed to PSL staleness."
346
+ ]
347
+ }
348
+ ],
349
+ "false_positive_profile": [
350
+ {
351
+ "indicator_id": "dnssec-validation-not-enforced",
352
+ "benign_pattern": "A configuration where the trust check is enforced upstream (validating resolver, authenticated time appliance, pinned private CA) or is genuinely not-in-scope for the deployment.",
353
+ "distinguishing_test": "A stub resolver that trusts a validated AD flag from a DNSSEC-validating upstream over an authenticated channel (e.g. DoT/DoH to a trusted resolver) is safe; the finding is a path that neither validates locally nor trusts a validated upstream."
354
+ },
355
+ {
356
+ "indicator_id": "dane-tlsa-not-checked",
357
+ "benign_pattern": "A configuration where the trust check is enforced upstream (validating resolver, authenticated time appliance, pinned private CA) or is genuinely not-in-scope for the deployment.",
358
+ "distinguishing_test": "DANE applies where the peer publishes TLSA AND the resolver validates DNSSEC; a peer with no TLSA record is web-PKI-only and not this finding."
359
+ },
360
+ {
361
+ "indicator_id": "unauthenticated-ntp-no-nts",
362
+ "benign_pattern": "A configuration where the trust check is enforced upstream (validating resolver, authenticated time appliance, pinned private CA) or is genuinely not-in-scope for the deployment.",
363
+ "distinguishing_test": "A host with an authenticated time source (NTS, a GPS/PTP appliance, or an authenticated internal time service) is safe; the finding is network-NTP-only with no authentication."
364
+ },
365
+ {
366
+ "indicator_id": "tsig-absent-on-zone-operations",
367
+ "benign_pattern": "A configuration where the trust check is enforced upstream (validating resolver, authenticated time appliance, pinned private CA) or is genuinely not-in-scope for the deployment.",
368
+ "distinguishing_test": "A nameserver that restricts AXFR to TSIG-keyed secondaries (or to no external peers at all) is safe; the finding is AXFR/update reachable without TSIG."
369
+ },
370
+ {
371
+ "indicator_id": "mtls-ca-not-pinned",
372
+ "benign_pattern": "A configuration where the trust check is enforced upstream (validating resolver, authenticated time appliance, pinned private CA) or is genuinely not-in-scope for the deployment.",
373
+ "distinguishing_test": "A service mesh / internal mTLS that pins the private issuing CA (or peer SPKI) is safe; the finding is mTLS validating against the full public CA bundle where a private CA is expected."
374
+ },
375
+ {
376
+ "indicator_id": "http-message-signature-not-verified",
377
+ "benign_pattern": "A configuration where the trust check is enforced upstream (validating resolver, authenticated time appliance, pinned private CA) or is genuinely not-in-scope for the deployment.",
378
+ "distinguishing_test": "Confirm the verifier checks the signature AND that the covered-components include method, @target-uri, content-digest, and a created/expires window — a verifier that accepts unsigned, or whose signature omits the body digest, is the finding."
379
+ },
380
+ {
381
+ "indicator_id": "dns-rebinding-unguarded",
382
+ "benign_pattern": "A configuration where the trust check is enforced upstream (validating resolver, authenticated time appliance, pinned private CA) or is genuinely not-in-scope for the deployment.",
383
+ "distinguishing_test": "A resolver that pins the checked IP for the lifetime of the connection AND refuses private/link-local/loopback/metadata addresses is safe; the finding is re-resolution or unfiltered private-range answers."
384
+ },
385
+ {
386
+ "indicator_id": "public-suffix-list-stale",
387
+ "benign_pattern": "A configuration where the trust check is enforced upstream (validating resolver, authenticated time appliance, pinned private CA) or is genuinely not-in-scope for the deployment.",
388
+ "distinguishing_test": "A PSL refreshed within its currency window (or pinned to a recent vendored copy with a refresh job) is safe; the finding is a years-stale or absent PSL driving cookie/domain decisions."
389
+ }
390
+ ],
391
+ "minimum_signal": {
392
+ "detected": "At least one network-trust anchor is unvalidated on a production path — DNSSEC not enforced, DANE/TLSA unchecked on a capable peer, time unauthenticated, TSIG absent on exposed zone ops, mTLS unpinned, message signatures unverified, or DNS rebinding unguarded.",
393
+ "inconclusive": "A trust check is enforced by infrastructure the audit could not read (a validating-resolver appliance, a time appliance) — record as visibility_gap, not a clean result.",
394
+ "not_detected": "The application path validates DNSSEC (or trusts a validated upstream over an authenticated channel), checks DANE/TLSA where published, uses authenticated time, requires TSIG on zone ops, pins the expected mTLS CA, verifies adequately-scoped message signatures, and guards against DNS rebinding."
395
+ }
396
+ },
397
+ "analyze": {
398
+ "rwep_inputs": [
399
+ {
400
+ "signal_id": "dnssec-validation-not-enforced",
401
+ "rwep_factor": "blast_radius",
402
+ "weight": 25
403
+ },
404
+ {
405
+ "signal_id": "dane-tlsa-not-checked",
406
+ "rwep_factor": "active_exploitation",
407
+ "weight": 10
408
+ },
409
+ {
410
+ "signal_id": "unauthenticated-ntp-no-nts",
411
+ "rwep_factor": "public_poc",
412
+ "weight": 20
413
+ }
414
+ ],
415
+ "blast_radius_model": {
416
+ "scope_question": "How many trust decisions (peer auth, name resolution, cert validity, TOTP) ride on the unvalidated anchor, and is the path internet-exposed?",
417
+ "scoring_rubric": [
418
+ {
419
+ "condition": "An internet-facing path where forged DNS or a mis-issued cert redirects authentication / credential / payment traffic",
420
+ "blast_radius_score": 5,
421
+ "description": "AiTM yields credential capture or traffic redirection at scale"
422
+ },
423
+ {
424
+ "condition": "Time-trust gap affecting cert-validity / TOTP across many hosts",
425
+ "blast_radius_score": 4,
426
+ "description": "Clock shift revives expired certs or shifts auth windows fleet-wide"
427
+ },
428
+ {
429
+ "condition": "Internal-only path behind strong network segmentation",
430
+ "blast_radius_score": 2,
431
+ "description": "Exploitation requires an on-path position inside the perimeter"
432
+ }
433
+ ]
434
+ },
435
+ "compliance_theater_check": {
436
+ "claim": "We use TLS everywhere, a validating resolver, and NTP, so the network is trustworthy.",
437
+ "audit_evidence": "TLS certificates, a resolver configured with DNSSEC, an NTP client.",
438
+ "reality_test": "Confirm the application path validates DNSSEC end-to-end, checks DANE/TLSA on capable peers (or pins the mTLS CA), and uses authenticated time. If a forged DNS answer, a mis-issued cert, or a time shift would be accepted, TLS did not make the network trustworthy.",
439
+ "theater_verdict_if_gap": "theater"
440
+ },
441
+ "framework_gap_mapping": [
442
+ {
443
+ "finding_id": "dnssec-validation-not-enforced",
444
+ "framework": "nist-800-53",
445
+ "claimed_control": "SC-20 (secure name resolution)",
446
+ "actual_gap": "SC-20 names DNSSEC but is attested by a resolver setting, not end-to-end application trust of validated answers."
447
+ },
448
+ {
449
+ "finding_id": "dane-tlsa-not-checked",
450
+ "framework": "nist-800-53",
451
+ "claimed_control": "SC-8 (transmission integrity)",
452
+ "actual_gap": "SC-8 is satisfied by TLS to a CA bundle; it does not require DANE pinning, so a mis-issued valid cert passes."
453
+ }
454
+ ],
455
+ "escalation_criteria": [
456
+ {
457
+ "condition": "An internet-facing authentication / payment path resolves names without DNSSEC and pins no peer cert (DANE/mTLS)",
458
+ "action": "raise_severity"
459
+ },
460
+ {
461
+ "condition": "Unauthenticated time drives cert-validity or TOTP on production auth",
462
+ "action": "trigger_playbook"
463
+ }
464
+ ]
465
+ },
466
+ "validate": {
467
+ "remediation_paths": [
468
+ {
469
+ "id": "enforce-dnssec-and-rebinding-guard",
470
+ "description": "Validate DNSSEC end-to-end (or trust a validating upstream over DoT/DoH), prefer signed answers, and pin the resolved IP for the connection lifetime while refusing private/link-local/metadata addresses.",
471
+ "preconditions": [
472
+ "resolver path is operator-controlled"
473
+ ],
474
+ "priority": 1,
475
+ "for_signals": [
476
+ "dnssec-validation-not-enforced",
477
+ "dns-rebinding-unguarded"
478
+ ]
479
+ },
480
+ {
481
+ "id": "pin-peer-certificates",
482
+ "description": "Check DANE/TLSA on DANE-capable peers (server-to-server / MTA) and pin the expected private CA or SPKI on mTLS instead of trusting the full public CA bundle.",
483
+ "preconditions": [],
484
+ "priority": 1,
485
+ "for_signals": [
486
+ "dane-tlsa-not-checked",
487
+ "mtls-ca-not-pinned"
488
+ ]
489
+ },
490
+ {
491
+ "id": "authenticate-time",
492
+ "description": "Synchronise time over NTS or an authenticated source, and treat the clock as a trust input for cert-validity and TOTP verification.",
493
+ "preconditions": [],
494
+ "priority": 2,
495
+ "for_signals": [
496
+ "unauthenticated-ntp-no-nts"
497
+ ]
498
+ },
499
+ {
500
+ "id": "require-tsig-and-verify-signatures",
501
+ "description": "Require TSIG (or SIG(0)) on AXFR/IXFR and dynamic updates, and verify RFC 9421 HTTP message signatures with method + @target-uri + content-digest + created/expires in the covered components.",
502
+ "preconditions": [],
503
+ "priority": 2,
504
+ "for_signals": [
505
+ "tsig-absent-on-zone-operations",
506
+ "http-message-signature-not-verified"
507
+ ]
508
+ },
509
+ {
510
+ "id": "refresh-public-suffix-list",
511
+ "description": "Pin a recent Public Suffix List with a refresh job so cookie-scope and domain-boundary decisions use a current registrable-domain table.",
512
+ "preconditions": [],
513
+ "priority": 3,
514
+ "for_signals": [
515
+ "public-suffix-list-stale"
516
+ ]
517
+ }
518
+ ],
519
+ "validation_tests": [
520
+ {
521
+ "id": "forged-dns-rejected",
522
+ "test": "Serve a forged answer for a DNSSEC-signed name the application resolves.",
523
+ "expected_result": "Resolution fails validation; the forged answer is not used.",
524
+ "test_type": "negative"
525
+ },
526
+ {
527
+ "id": "mis-issued-cert-rejected",
528
+ "test": "Present a valid CA-issued certificate for a DANE-pinned (or mTLS-pinned) peer that does not match the published TLSA / pinned CA.",
529
+ "expected_result": "Connection refused — peer identity does not match the pin.",
530
+ "test_type": "negative"
531
+ },
532
+ {
533
+ "id": "time-shift-does-not-revive-cert",
534
+ "test": "Shift the host clock (where unauthenticated) and present an expired certificate.",
535
+ "expected_result": "With authenticated time, the clock cannot be shifted and the expired cert is refused.",
536
+ "test_type": "negative"
537
+ },
538
+ {
539
+ "id": "legitimate-traffic-flows",
540
+ "test": "Resolve and connect to a legitimate, correctly-pinned peer over the hardened path.",
541
+ "expected_result": "Connection succeeds — no regression on the legitimate path.",
542
+ "test_type": "functional"
543
+ }
544
+ ],
545
+ "residual_risk_statement": {
546
+ "risk": "A compromise of the DNSSEC signing key, the pinned CA, or the time authority itself still yields a trusted-but-forged answer.",
547
+ "why_remains": "Trust-anchor validation moves trust to the anchor; compromise of the anchor is handled by key-management and monitoring, not by the validating client.",
548
+ "acceptance_level": "ciso"
549
+ },
550
+ "evidence_requirements": [
551
+ {
552
+ "evidence_type": "config_diff",
553
+ "description": "The DNSSEC, DANE/TSIG, time-sync, mTLS-pin, message-signature, and PSL configuration as audited.",
554
+ "retention_period": "1 year"
555
+ },
556
+ {
557
+ "evidence_type": "exploit_replay_negative",
558
+ "description": "Outcomes of the forged-DNS / mis-issued-cert / time-shift negative tests plus the legitimate-path functional test.",
559
+ "retention_period": "1 year"
560
+ }
561
+ ],
562
+ "regression_trigger": [
563
+ {
564
+ "condition": "A new resolver / CA / time source / DANE-capable peer is introduced",
565
+ "interval": "on change"
566
+ },
567
+ {
568
+ "condition": "Periodic re-attestation of network-trust posture",
569
+ "interval": "quarterly"
570
+ }
571
+ ]
572
+ },
573
+ "close": {
574
+ "evidence_package": {
575
+ "bundle_format": "csaf-2.0",
576
+ "contents": [
577
+ "network-trust config snapshot",
578
+ "per-indicator findings + false-positive disposition",
579
+ "negative + functional test results",
580
+ "framework gap mapping"
581
+ ],
582
+ "destination": ".exceptd/attestations/<session_id>/attestation.json"
583
+ },
584
+ "learning_loop": {
585
+ "enabled": true,
586
+ "lesson_template": {
587
+ "attack_vector": "Adversary-in-the-middle beneath TLS — forged DNS (no DNSSEC), mis-issued cert (no DANE/mTLS pin), shifted clock (no NTS), or DNS rebinding — accepted because the trust anchor was not validated.",
588
+ "control_gap": "Application path does not validate DNSSEC / DANE-TLSA / authenticated time / mTLS pin / message signatures.",
589
+ "framework_gap": "NIST SC-8 + SC-20 + NIS2 Art.21 equate TLS with peer authenticity and assume DNS/time are trustworthy.",
590
+ "new_control_requirement": "The path MUST validate DNS authenticity (DNSSEC), pin the expected peer (DANE/mTLS), and use authenticated time."
591
+ }
592
+ },
593
+ "notification_actions": [
594
+ {
595
+ "obligation_ref": "EU/NIS2 Art.23 24h",
596
+ "deadline": "24h from detect_confirmed",
597
+ "recipient": "national CSIRT / competent authority",
598
+ "evidence_attached": [
599
+ "attestation"
600
+ ]
601
+ },
602
+ {
603
+ "obligation_ref": "EU/eIDAS Art.19 24h",
604
+ "deadline": "24h from detect_confirmed",
605
+ "recipient": "trust-service supervisory body",
606
+ "evidence_attached": [
607
+ "attestation"
608
+ ]
609
+ }
610
+ ],
611
+ "exception_generation": {
612
+ "trigger_condition": "A peer or zone cannot adopt DNSSEC/DANE in time (e.g. a third party with no signed zone).",
613
+ "exception_template": {
614
+ "scope": "the specific peer / resolution path",
615
+ "duration": "90 days",
616
+ "compensating_controls": [
617
+ "mTLS or SPKI pin to the specific peer",
618
+ "authenticated-channel resolver (DoT/DoH to a trusted resolver)",
619
+ "enhanced logging of certificate + DNS-answer changes"
620
+ ],
621
+ "risk_acceptance_owner": "ciso"
622
+ }
623
+ },
624
+ "regression_schedule": {
625
+ "next_run": "quarterly or on any new resolver / CA / time source change",
626
+ "trigger": "change to DNS/time/CA trust anchors, or quarterly re-attestation"
627
+ }
628
+ }
629
+ },
630
+ "directives": [
631
+ {
632
+ "id": "all-network-trust-paths",
633
+ "title": "Inventory + validate every DNS / TLS-peer / time / message-signature trust anchor",
634
+ "applies_to": {
635
+ "always": true
636
+ }
637
+ },
638
+ {
639
+ "id": "aitm-resistance-sweep",
640
+ "title": "Targeted AiTM-resistance sweep (DNSSEC + DANE + authenticated time) on internet-facing paths",
641
+ "applies_to": {
642
+ "attack_technique": "T1557"
643
+ }
644
+ }
645
+ ]
646
+ }