fix: audit remediation — webapp XSS/CSP, CI/script hardening, ATLAS registry gap, spelling - #216
Merged
Merged
Conversation
…TLAS registry, spelling Addresses verified findings from the full-repo security/cohesion/precision audit. Security: - M1 docs/index.html: escape user-submitted JSON (fw.name, control_id error list, parse-error message) via the existing esc() before innerHTML in the framework-submission validator (self-XSS sink, but unacceptable on an OWASP app) - L3 docs/index.html: add a Content-Security-Policy meta (default-src self; inline allowed since the app is fully inline; egress limited to api.github.com; d3 from jsDelivr) + SRI-pin the dynamically-loaded d3@7.8.5 script - L1 .github/workflows/crosswalk-check.yml: pass github.base_ref via env and use execFileSync(argv) instead of interpolating into an execSync shell string - L2 scripts/ingest-framework.mjs: reject non-slug framework ids and assert the resolved path stays in data/frameworks/ (defense-in-depth; schema already pins the id pattern) Cohesion / precision: - M3 data/frameworks/mitre-atlas.json: add 4 techniques cited by entry mappings but missing from the local registry — AML.T0021, T0053, T0060, T0066 (all present in current upstream ATLAS). Clears 10 mapping->registry misses; 43->47. Total controls 1,507 -> 1,511 (propagated to README, CITATION, banner, og-image). - L6 spelling: align DSGAI10 entry name to the documented British canonical "Anonymisation" in generate.js META + CROSSREF.md (the "ARX Data Anonymization" product name and body prose are correctly left as-is). Regenerated entries/mirrors. Not in scope (tracked separately): M2 prose-vs-formal-code control_id schism across ~9 frameworks (deliberate-looking authoring choice — needs a design call); L5 classifier-split staleness vs current mappings (resolves on next split regen). validate.js 0/0/385; markdownlint clean; traversal guard self-tested.
Contributor
🛡️ OWASP GenAI Security CrosswalkThis PR modifies 5 AI-related file(s). The following OWASP GenAI risks may be relevant:
🔍 Scanned 17 changed files · Found 15 potential risks · Full crosswalk · Gap analysis |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Remediation batch for the verified findings from a full-repo security / cohesion / precision audit (4 parallel auditors → high/medium claims re-computed or read against the code; several auditor claims were disproven and excluded).
Security
docs/index.html). User-pasted JSON (fw.name, the duplicate-control_iderror list, JSON parse-error message) flowed intoinnerHTMLunescaped. Now wrapped in the existingesc(). Self-XSS in practice (the form only builds a GitHub issue link — nothing is persisted or served to other viewers; the auditor's "stored XSS" framing was wrong), but no XSS sink belongs in an OWASP reference app.docs/index.html). Added a CSP<meta>:default-src 'self', inline allowed (the app is entirely inline scripts/styles/handlers —'unsafe-inline'is unavoidable without a refactor), network egress limited toapi.github.com, scripts to self + jsDelivr, plusobject-src 'none'/base-uri 'self'/frame-ancestors 'none'. Also SRI-pinned the dynamically-loadedd3@7.8.5(integrity+crossorigin)..github/workflows/crosswalk-check.yml).github.base_refnow passed viaenv:and consumed withexecFileSync('git', [...])instead of being interpolated into anexecSyncshell string. (Not externally exploitable —base_refis the target branch, not fork-controlled — but this file is a template meant to be copied into other repos, so the pattern matters.)scripts/ingest-framework.mjs). Reject non-slug framework ids and assert the resolved path stays insidedata/frameworks/. Defense-in-depth: the schema already enforces the id pattern (verified — a../evilid is rejected at validation), and the workflow is maintainer-label-gated, so this was low-risk; the explicit guard makes it obvious.Cohesion / precision
data/frameworks/mitre-atlas.json). 10 entry mappings cited 4 techniques valid in current upstream ATLAS but absent from the local 43-entry registry (trimmed in fix(atlas): reconcile MITRE ATLAS framework data v4.0 -> v5.6.0 (#187) #211). AddedAML.T0021Establish Accounts,AML.T0053AI Agent Tool Invocation,AML.T0060Publish Hallucinated Entities,AML.T0066Retrieval Content Crafting (authoritative titles + concise GenAI-style descriptions, registry changelog entry). Registry 43 → 47; mapping→registry misses 10 → 0. Total controls 1,507 → 1,511, propagated to README badge/text,CITATION.cff,banner.svg,og-image.svg.scripts/generate.jsMETA — the real source — andCROSSREF.md), matching the deliberate DSGAI heading normalization. The "ARX Data Anonymization" product name (a real tool) and body prose are deliberately left untouched. Regenerateddata/entries/*,data/backlinks.json,docs/{data,backlinks,frameworks-registry}.js.Explicitly out of scope (tracked, not fixed here)
control_idschism. ~341 of 3,351 mappings (SOC 2, EU AI Act, FedRAMP, NHI, 800-218A/82, AITG…) carry bespoke prosecontrol_ids that don't join the registry's formal codes (the formal code sits incontrol_name). Looks like a deliberate authoring pattern across 9 frameworks — needs a design decision, not a blind rewrite.10f2372; non-ATLAS frameworks drifted). Eval-only; resolves on the next split regeneration. Hashes all valid.Disproven auditor claims (excluded)
CWE/CVE "38 duplicate control_ids" → zero duplicates in any framework; AIUC-1 "mapping tables as controls" → only 2 formal misses; webapp "stored XSS affecting other viewers" → self-XSS; "controls should be 1,514" → 1,514 was a pre-#211 milestone, the computed figure is 1,511 after this PR.
Verification
node scripts/validate.js→ 0 errors / 0 warnings / 385 passedmarkdownlint README.md CROSSREF.md→ clean../evil); ATLAS misses recomputed to 0🤖 Generated with Claude Code