Skip to content

Commit fdd9d9f

Browse files
committed
fix: harden SVG sanitization against XSS vectors
1 parent ea059a6 commit fdd9d9f

1 file changed

Lines changed: 13 additions & 5 deletions

File tree

app/customize/page.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { motion } from 'framer-motion';
66
import { ControlsPanel } from './components/ControlsPanel';
77
import { ExportPanel } from './components/ExportPanel';
88
import InteractiveViewer from '@/components/InteractiveViewer';
9+
import DOMPurify from 'dompurify';
910
import type {
1011
ExportFormat,
1112
Font,
@@ -142,11 +143,18 @@ export default function CustomizePage(): ReactElement {
142143
})
143144
.then((text) => {
144145
if (!text) return;
145-
// Basic SVG sanitization to prevent XSS (strip scripts and inline event handlers)
146-
const sanitized = text
147-
.replace(/<script[\s\S]*?>[\s\S]*?<\/script>/gi, '')
148-
.replace(/on\w+\s*=\s*("[^"]*"|'[^']*')/gi, '');
149-
setSvgContent(sanitized);
146+
// Sanitize SVG using DOMPurify with the SVG profile.
147+
// - Forbid risky tags like foreignObject and embedded content
148+
// - Forbid xlink:href to avoid external references
149+
// - Use a conservative URI whitelist to prevent javascript: URIs
150+
const sanitized = DOMPurify.sanitize(text, {
151+
USE_PROFILES: { svg: true },
152+
FORBID_TAGS: ['foreignObject', 'iframe', 'object', 'embed', 'script'],
153+
FORBID_ATTR: ['xlink:href'],
154+
ALLOWED_URI_REGEXP: /^(?:(?:https?|mailto|data):|#)/i,
155+
});
156+
157+
setSvgContent(sanitized as string);
150158
setSvgState('loaded');
151159
setErrorMessage(null);
152160
})

0 commit comments

Comments
 (0)