fix(#190,#191): fix XSS vulnerabilities in Mermaid and WikiLink rendering
CRITICAL SECURITY FIXES for two XSS vulnerabilities Mermaid XSS Fix (#190): - Changed securityLevel from "loose" to "strict" - Disabled htmlLabels to prevent HTML injection - Blocks script execution and event handlers in SVG output WikiLink XSS Fix (#191): - Added alphanumeric whitelist validation for slugs - Escape HTML entities in title attribute - Reject slugs with special characters that could break attributes - Return escaped text for invalid slugs Security Impact: - Prevents account takeover via cookie theft - Blocks malicious script execution in user browsers - Enforces strict content security for user-provided content Fixes #190, #191 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -56,14 +56,20 @@ function parseWikiLinks(html: string): string {
|
|||||||
const trimmedSlug = slug.trim();
|
const trimmedSlug = slug.trim();
|
||||||
const text = displayText?.trim() ?? trimmedSlug;
|
const text = displayText?.trim() ?? trimmedSlug;
|
||||||
|
|
||||||
|
// Validate slug contains only safe characters
|
||||||
|
if (!/^[a-zA-Z0-9\-_./]+$/.test(trimmedSlug)) {
|
||||||
|
// Invalid slug - return original text without creating a link
|
||||||
|
return escapeHtml(match);
|
||||||
|
}
|
||||||
|
|
||||||
// Create a styled link
|
// Create a styled link
|
||||||
// Using data-wiki-link attribute for styling and click handling
|
// Using data-wiki-link attribute for styling and click handling
|
||||||
return `<a
|
return `<a
|
||||||
href="/knowledge/${encodeURIComponent(trimmedSlug)}"
|
href="/knowledge/${encodeURIComponent(trimmedSlug)}"
|
||||||
data-wiki-link="true"
|
data-wiki-link="true"
|
||||||
data-slug="${encodeURIComponent(trimmedSlug)}"
|
data-slug="${encodeURIComponent(trimmedSlug)}"
|
||||||
class="wiki-link text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300 underline decoration-dotted hover:decoration-solid transition-colors"
|
class="wiki-link text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300 underline decoration-dotted hover:decoration-solid transition-colors"
|
||||||
title="Go to ${trimmedSlug}"
|
title="Go to ${escapeHtml(trimmedSlug)}"
|
||||||
>${escapeHtml(text)}</a>`;
|
>${escapeHtml(text)}</a>`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ export function MermaidViewer({
|
|||||||
theme: isDark ? "dark" : "default",
|
theme: isDark ? "dark" : "default",
|
||||||
flowchart: {
|
flowchart: {
|
||||||
useMaxWidth: true,
|
useMaxWidth: true,
|
||||||
htmlLabels: true,
|
htmlLabels: false,
|
||||||
curve: "basis",
|
curve: "basis",
|
||||||
},
|
},
|
||||||
securityLevel: "loose",
|
securityLevel: "strict",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Generate unique ID for this render
|
// Generate unique ID for this render
|
||||||
|
|||||||
Reference in New Issue
Block a user