fix: Resolve CodeQL security findings (CSRF, regex, dynamic method call)#107
Conversation
- anchor-modal.js: Validate anchorId against safe pattern before use in fetch() URLs (fixes js/client-side-request-forgery x3) Also validate lang code before use in URL - router.js: Validate anchorId from URL hash before passing to showAnchorDetails (fixes js/unvalidated-dynamic-method-call) - website.spec.js: Anchor GitHub URL regex to prevent partial host matching (fixes js/regex/missing-regexp-anchor) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix: Resolve CodeQL security findings
WalkthroughDer Pull Request fügt Input-Validierung für Anchor-IDs und Sprachbehandlung hinzu. In anchor-modal.js werden anchorId und Sprache validiert mit Fallbacks zu Englisch. In router.js wird die Anchor-ID vor der Weiterverarbeitung überprüft. In website.spec.js wird eine Test-Assertion für GitHub-URLs verschärft. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
website/src/components/anchor-modal.js (1)
170-181: Defense-in-Depth: Optional anchorId-Validierung für Cross-References.Die
anchorIdaus internen AsciiDoc-Cross-References (Zeile 174) wird ohne Validierung inwindow.location.hasheingefügt. Obwohlrouter.jsdie ID später validiert, könnte eine zusätzliche Prüfung hier schädliche Cross-References früher abfangen.🛡️ Vorgeschlagene Änderung
contentEl.querySelectorAll('a[href^="#"]').forEach((link) => { const href = link.getAttribute('href') // Only process simple hash links (cross-references), not hash routes if (href && href.startsWith('#') && !href.startsWith('#/')) { const anchorId = href.substring(1) // Remove the '#' + if (!SAFE_ANCHOR_ID.test(anchorId)) return link.addEventListener('click', (e) => { e.preventDefault() // Navigate to the linked anchor window.location.hash = `#/anchor/${anchorId}` }) } })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/src/components/anchor-modal.js` around lines 170 - 181, Validate the extracted anchorId before writing it into window.location.hash to provide defense-in-depth: inside the contentEl.querySelectorAll('a[href^="#"]') loop (where anchorId is set and link.addEventListener is added), check anchorId against a safe pattern (e.g. allow only alphanumerics and a limited set of safe punctuation like - _ : .) and skip or ignore the click (after e.preventDefault()) if the anchorId fails validation; keep router.js validation but do not forward unsafe values into window.location.hash and optionally log/console.warn when rejecting an invalid anchorId for debugging.website/src/utils/router.js (1)
54-54: Optional: Regex-Duplikation extrahieren.Dieselbe Regex
/^[a-z0-9]+(?:-[a-z0-9]+)*$/wird sowohl hier als auch inanchor-modal.js(Zeile 109 alsSAFE_ANCHOR_ID) definiert. Falls weitere Validierungsstellen hinzukommen, könnte ein gemeinsames Modul (z.B.utils/validation.js) die Wartbarkeit verbessern.Die aktuelle Duplikation ist jedoch als Defense-in-Depth-Ansatz vertretbar.
Also applies to: 109-109
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/src/utils/router.js` at line 54, Duplizierte Regex-Validierung für Anchor-IDs: extrahiere die Regex `/^[a-z0-9]+(?:-[a-z0-9]+)*$/` in ein gemeinsames Utility (z.B. export const SAFE_ANCHOR_ID or isValidAnchorId) und ersetze die inline-Checks in router.js (variable safeAnchorId) und anchor-modal.js (SAFE_ANCHOR_ID) durch einen Import aus utils/validation.js; stelle sicher, dass der Export sowohl die Regex als Konstanten als auch eine kleine Helferfunktion (isValidAnchorId) zur Verfügung stellt, damit zukünftige Validierungsstellen dieselbe Referenz nutzen.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@website/src/components/anchor-modal.js`:
- Around line 170-181: Validate the extracted anchorId before writing it into
window.location.hash to provide defense-in-depth: inside the
contentEl.querySelectorAll('a[href^="#"]') loop (where anchorId is set and
link.addEventListener is added), check anchorId against a safe pattern (e.g.
allow only alphanumerics and a limited set of safe punctuation like - _ : .) and
skip or ignore the click (after e.preventDefault()) if the anchorId fails
validation; keep router.js validation but do not forward unsafe values into
window.location.hash and optionally log/console.warn when rejecting an invalid
anchorId for debugging.
In `@website/src/utils/router.js`:
- Line 54: Duplizierte Regex-Validierung für Anchor-IDs: extrahiere die Regex
`/^[a-z0-9]+(?:-[a-z0-9]+)*$/` in ein gemeinsames Utility (z.B. export const
SAFE_ANCHOR_ID or isValidAnchorId) und ersetze die inline-Checks in router.js
(variable safeAnchorId) und anchor-modal.js (SAFE_ANCHOR_ID) durch einen Import
aus utils/validation.js; stelle sicher, dass der Export sowohl die Regex als
Konstanten als auch eine kleine Helferfunktion (isValidAnchorId) zur Verfügung
stellt, damit zukünftige Validierungsstellen dieselbe Referenz nutzen.
Summary
Fixes all 5 CodeQL security findings discovered after enabling CodeQL SAST.
Findings fixed
anchor-modal.js(3x)js/client-side-request-forgeryanchorIdbefore use infetch()router.jsjs/unvalidated-dynamic-method-callanchorIdfrom URL hashwebsite.spec.jsjs/regex/missing-regexp-anchorTest plan
npm run lint— 0 errorsnpm run format:check— cleannpm run test— 70 unit tests pass🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
Bug Fixes
Tests