Description
The static site export in ExportPanel.tsx injects entity.description directly into HTML without escaping. Since entity.description contains HTML from the TipTap editor, a user could inject arbitrary JavaScript that executes when the exported HTML page is opened.
Vulnerable Code
File: src/features/export/ExportPanel.tsx (lines ~159-160)
if (entity.description) {
// entity.description contains HTML from Tiptap editor.
// We preserve it to maintain formatting in the export.
html += `\n <div class="description">${entity.description}</div>\n`;
}
Impact
- Severity: Critical
- Attack vector: A user creates an entity with a description containing
<script> tags or event handlers (e.g., <img onerror="...">), then exports as HTML. Anyone opening the exported page executes the injected script.
- Impact: Arbitrary JavaScript execution in the context of the exported page (stealing cookies, redirecting users, defacing content).
Recommended Fix
- Sanitize
entity.description using DOMPurify before inserting into the export HTML
- Add
escapeHtml() for plain-text fields (already used for entity names/claims)
- Add Content Security Policy headers to exported HTML
- Add a security test case that verifies malicious HTML is stripped
Acceptance Criteria
Description
The static site export in
ExportPanel.tsxinjectsentity.descriptiondirectly into HTML without escaping. Sinceentity.descriptioncontains HTML from the TipTap editor, a user could inject arbitrary JavaScript that executes when the exported HTML page is opened.Vulnerable Code
File:
src/features/export/ExportPanel.tsx(lines ~159-160)Impact
<script>tags or event handlers (e.g.,<img onerror="...">), then exports as HTML. Anyone opening the exported page executes the injected script.Recommended Fix
entity.descriptionusing DOMPurify before inserting into the export HTMLescapeHtml()for plain-text fields (already used for entity names/claims)Acceptance Criteria
entity.descriptionis sanitized via DOMPurify before HTML exportescapeHtml()