Skip to content

Validate vulnerability id before use in the DOM (DOCS-106) - #3740

Merged
matthewhelmke merged 1 commit into
chainguard-dev:mainfrom
matthewhelmke:matthewhelmke/docs-106-fix-codeql-client-side-url-redirect-dom-xss-in-rumble
Aug 7, 2026
Merged

Validate vulnerability id before use in the DOM (DOCS-106)#3740
matthewhelmke merged 1 commit into
chainguard-dev:mainfrom
matthewhelmke:matthewhelmke/docs-106-fix-codeql-client-side-url-redirect-dom-xss-in-rumble

Conversation

@matthewhelmke

Copy link
Copy Markdown
Collaborator

What

Validate the vulnerability id at its source before it reaches the DOM, resolving the open CodeQL alert #97 (js/client-side-unvalidated-url-redirection, CWE-601 / CWE-79 / CWE-116) in assets/js/rumble/vulnerability.js.

getVulnID() is the single choke point: the id it returns (from the ?id= query param on preview/localhost, or the URL path segment in prod) flows into every DOM sink on the page — link.href (the flagged line), plus innerHTML and meta content. Guarding it once neutralizes all of them:

if (id && /^[A-Za-z0-9._-]{1,64}$/.test(id)) {
  return id;
}
return "";

Legitimate identifiers (CVE-2024-1234, GHSA-xxxx-xxxx-xxxx) pass unchanged; anything containing HTML/URL metacharacters is rejected. Also dropped a dead let id = "" initializer (both branches reassign it) that eslint's no-useless-assignment flagged.

Why validate at the source

The flagged sink (link.href += id on the canonical <link>) is low real-world risk on its own, but the same untrusted id is written unescaped to innerHTML a few lines up — a genuine DOM-XSS vector. Validating the shared source is cleaner and more robust than escaping each sink individually, and matches CodeQL's own "validate against an allowlist" recommendation.

Testing

  • Validation battery (Node): all legitimate IDs pass through unchanged; every attack vector returns ""<img src=x onerror=…>, "><script>, //evil.com, https://evil.com, javascript:…, ../../etc/passwd, query-string injection, an over-length string, and null/empty.
  • eslint clean on the changed file.
  • npm run build succeeds (JS bundles via Hugo/esbuild).
  • CodeQL should mark alert Add links to next steps at the end of the enforce onboarding doc #97 resolved once this runs on the PR / after merge.

Linear: DOCS-106


Created in collaboration with Claude Code running Opus 4.8 on 2026-08-07.

Guard the id returned by getVulnID() with a strict allowlist
(^[A-Za-z0-9._-]{1,64}$), returning "" for anything else. getVulnID is
the single source for the id that flows into every DOM sink on the page
(canonical link href, innerHTML, meta content), so validating once
neutralizes the CodeQL client-side URL redirect finding (chainguard-dev#97) and the
related DOM-XSS in the neighboring innerHTML sink.

Legitimate identifiers (CVE-..., GHSA-...) pass unchanged. Also drop a
dead `let id = ""` initializer that both branches immediately reassign.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@matthewhelmke
matthewhelmke requested a review from a team as a code owner August 7, 2026 18:06
@netlify

netlify Bot commented Aug 7, 2026

Copy link
Copy Markdown

Deploy Preview for ornate-narwhal-088216 ready!

Name Link
🔨 Latest commit 829e3c1
🔍 Latest deploy log https://app.netlify.com/projects/ornate-narwhal-088216/deploys/6a761ec40023d0000898e717
😎 Deploy Preview https://deploy-preview-3740--ornate-narwhal-088216.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@matthewhelmke
matthewhelmke merged commit 3af7d00 into chainguard-dev:main Aug 7, 2026
9 checks passed
@matthewhelmke
matthewhelmke deleted the matthewhelmke/docs-106-fix-codeql-client-side-url-redirect-dom-xss-in-rumble branch August 7, 2026 18:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants