Files
stack/docs/scratchpads/201-wikilink-xss-enhancement.md
Jason Woltje e57271c278
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
fix(#201): Enhance WikiLink XSS protection with comprehensive validation
Added defense-in-depth security layers for wiki-link rendering:

Slug Validation (isValidWikiLinkSlug):
- Reject empty slugs
- Block dangerous protocols: javascript:, data:, vbscript:, file:, about:, blob:
- Block URL-encoded dangerous protocols (e.g., %6A%61%76%61... = javascript)
- Block HTML tags in slugs
- Block HTML entities in slugs
- Only allow safe characters: a-z, A-Z, 0-9, -, _, ., /

Display Text Sanitization (DOMPurify):
- Strip all HTML tags from display text
- ALLOWED_TAGS: [] (no HTML allowed)
- KEEP_CONTENT: true (preserves text content)
- Prevents event handler injection
- Prevents iframe/object/embed injection

Comprehensive XSS Testing:
- 11 new attack vector tests
- javascript: URLs - blocked
- data: URLs - blocked
- vbscript: URLs - blocked
- Event handlers (onerror, onclick) - removed
- iframe/object/embed - removed
- SVG with scripts - removed
- HTML entity bypass - blocked
- URL-encoded protocols - blocked
- All 25 tests passing (14 existing + 11 new)

Files modified:
- apps/web/src/components/knowledge/WikiLinkRenderer.tsx
- apps/web/src/components/knowledge/__tests__/WikiLinkRenderer.test.tsx

Fixes #201

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 22:59:41 -06:00

2.5 KiB

Issue #201: Enhance WikiLink XSS protection

Objective

Add comprehensive XSS validation for wiki-style links link to prevent all attack vectors.

Current State

  • WikiLinkRenderer already has basic XSS protection:
    • Validates slug format with regex
    • Escapes HTML in display text
    • Has 1 XSS test for script tags
  • Need to enhance with comprehensive attack vector testing

Attack Vectors to Test

  1. [[javascript:alert(1)|Click here]] - JavaScript URLs in slug
  2. [[data:text/html,<script>alert(1)</script>|Link]] - Data URLs in slug
  3. [[valid-link|<img src=x onerror=alert(1)>]] - Event handlers in display text
  4. [[valid-link|<iframe src=evil.com>]] - Iframe injection in display text
  5. [[<script>alert(1)</script>|text]] - Script in slug
  6. [[vbscript:alert(1)|text]] - VBScript URLs
  7. HTML entity bypass attempts

Implementation Plan

  • Create scratchpad
  • Add comprehensive XSS tests (TDD) - 11 new tests
  • Enhance slug validation
  • Enhance display text sanitization
  • Verify all tests pass (25/25 passing)
  • Check 85%+ coverage
  • Type checking passing
  • Commit and close issue

Changes Made

WikiLinkRenderer.tsx

  • Imported DOMPurify
  • Added isValidWikiLinkSlug() function:
    • Rejects empty slugs
    • Blocks dangerous protocols (javascript:, data:, vbscript:, file:, about:, blob:)
    • Blocks URL-encoded dangerous protocols
    • Blocks HTML tags in slugs
    • Blocks HTML entities in slugs
    • Only allows safe characters: a-z, A-Z, 0-9, -, _, ., /
  • Enhanced parseWikiLinks() to use DOMPurify for display text:
    • ALLOWED_TAGS: [] (no HTML allowed)
    • KEEP_CONTENT: true (preserves text content)
    • Completely strips all HTML from display text

WikiLinkRenderer.test.tsx

  • Added 11 comprehensive XSS attack tests:
    • javascript: URLs in slug
    • data: URLs in slug
    • vbscript: URLs in slug
    • Event handlers in display text
    • iframe injection
    • script tags in slug
    • onclick handlers
    • HTML entity bypass
    • URL-encoded protocols
    • SVG with scripts
    • object/embed tags
  • All 25 tests passing (14 existing + 11 new)

Security Improvements

  • Defense-in-depth: Multiple layers of validation
  • Slug validation prevents malicious URLs at source
  • DOMPurify removes all HTML from display text
  • HTML escaping as final layer
  • Comprehensive test coverage for all attack vectors

Files to Modify

  • apps/web/src/components/knowledge/WikiLinkRenderer.tsx
  • apps/web/src/components/knowledge/tests/WikiLinkRenderer.test.tsx