The wiki uses rehype-sanitize to protect against XSS (Cross-Site Scripting) and HTML injection attacks while allowing safe HTML elements needed for wiki features.
- ✅ Script injection (
<script>tags) - ✅ Event handler injection (
onclick,onerror,onload, etc.) - ✅ JavaScript URLs (
javascript:protocol) - ✅ Data URI attacks (except safe image data URLs)
- ✅ iframe/object/embed injection
- ✅ Form injection
- ✅ Meta tag manipulation
- ✅ Style injection with malicious CSS
The sanitization schema allows only these safe HTML elements with specific attributes:
<span class="text-red-500">Colored text</span>
<span class="text-blue-600">Blue text</span>- Element:
<span> - Allowed attributes:
class(only classes starting withtext-) - Use case: Text color formatting via Tailwind CSS classes
<img src="/path/to/image.png" alt="Description" />
<img src="https://example.com/image.jpg" alt="External image" />- Element:
<img> - Allowed attributes:
src,alt,title,width,height - Allowed protocols:
http,https,/(relative paths) - Blocked:
javascript:,data:,blob:schemes
<div align="center">Centered text</div>
<div align="right">Right-aligned text</div>- Element:
<div> - Allowed attributes:
align(values:left,center,right) - Use case: Text alignment
<h1 id="section-name">Section Title</h1>
<h2 id="subsection">Subsection</h2>- Elements:
<h1>through<h6> - Allowed attributes:
id(for anchor links) - Use case: Table of contents navigation
All HTML elements not explicitly allowed are stripped, including:
<script>- JavaScript execution<iframe>- Embedding external content<object>- Plugin content<embed>- Embedded content<form>- Form submission<input>- User input<button>- Interactive elements<link>- External resources<style>- Inline styles<meta>- Metadata manipulation<base>- Base URL manipulation
All event handlers and dangerous attributes are stripped:
onclick,onmouseover,onerror,onload(allon*attributes)style(inline styles that could containjavascript:)formaction,action(form submission)- Any attributes not explicitly allowed
The sanitization does not affect custom markdown comment syntax:
<!-- skill:Fire Slash -->
<!-- equipment:Legendary Sword -->These are processed before HTML rendering and converted to React components, bypassing HTML parsing entirely.
- Content Processing - Custom syntax (
<!-- skill:X -->) is processed first - Markdown Parsing -
remark-gfmparses markdown to HTML - HTML Parsing -
rehype-rawallows raw HTML in markdown - Sanitization -
rehype-sanitizefilters dangerous HTML⚠️ CRITICAL - Syntax Highlighting -
rehype-highlightadds code syntax highlighting - Anchor Links -
rehype-slugandrehype-autolink-headingsadd navigation
Order matters: Sanitization must come after rehype-raw to properly sanitize the parsed HTML.
File: wiki-framework/src/components/wiki/PageViewer.jsx
const sanitizeSchema = {
...defaultSchema,
attributes: {
...defaultSchema.attributes,
span: [...(defaultSchema.attributes.span || []), 'className', ['className', /^text-/]],
img: ['src', 'alt', 'title', 'width', 'height'],
div: [...(defaultSchema.attributes.div || []), 'align', ['align', /^(left|center|right)$/]],
// ... headings with id
},
protocols: {
...defaultSchema.protocols,
src: ['http', 'https', '/'],
href: ['http', 'https', 'mailto', '/', '#'],
},
};These should render correctly:
<!-- Safe colored text -->
<span class="text-red-500">Red text</span>
<!-- Safe image -->
<img src="/images/logo.png" alt="Logo" />
<!-- Safe alignment -->
<div align="center">Centered content</div>These will be stripped/sanitized:
<!-- Script injection - BLOCKED -->
<script>alert('XSS')</script>
<!-- Event handler - BLOCKED -->
<img src="x" onerror="alert('XSS')" />
<!-- JavaScript URL - BLOCKED -->
<a href="javascript:alert('XSS')">Click</a>
<!-- Iframe injection - BLOCKED -->
<iframe src="https://evil.com"></iframe>
<!-- Dangerous class - BLOCKED -->
<span class="malicious-class">Text</span>- Use markdown syntax when possible - Safer than raw HTML
- Use toolbar features - Color picker, image inserter are pre-sanitized
- Test in preview - Verify your content renders correctly
- Report issues - If legitimate content is being blocked, report it
- Never bypass sanitization - Don't use
dangerouslySetInnerHTML - Extend carefully - When adding allowed elements, consider security implications
- Review PRs - Check for changes to
sanitizeSchema - Keep dependencies updated -
rehype-sanitizemay have security patches - Audit regularly - Review allowed elements and attributes periodically
Last reviewed: 2025-12-15 Version: 1.0.0 Maintainer: Claude Code Team
When updating allowed HTML:
- Review the security implications
- Add the element/attribute to
sanitizeSchema - Test with malicious payloads
- Document the change here
- Update tests
If you discover a security vulnerability:
- Do not create a public issue
- Report via private channel to repository maintainers
- Include proof of concept (sanitized)
- Allow time for patch before disclosure