fix(frontend): remove isomorphic-dompurify for Cloudflare Workers compatibility
This commit is contained in:
@@ -18,8 +18,7 @@
|
|||||||
"agentation": "^2.1.1",
|
"agentation": "^2.1.1",
|
||||||
"agentation-mcp": "^1.1.0",
|
"agentation-mcp": "^1.1.0",
|
||||||
"astro": "6.0.0-beta.17",
|
"astro": "6.0.0-beta.17",
|
||||||
"better-auth": "^1.3.13",
|
"better-auth": "^1.3.13"
|
||||||
"isomorphic-dompurify": "^3.0.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@astrojs/check": "^0.9.6",
|
"@astrojs/check": "^0.9.6",
|
||||||
|
|||||||
@@ -1,64 +1,41 @@
|
|||||||
/**
|
/**
|
||||||
* SVG sanitization utilities
|
* SVG sanitization utilities
|
||||||
* Prevents XSS attacks from user-provided SVG content
|
* Prevents XSS attacks from user-provided SVG content
|
||||||
|
*
|
||||||
|
* Note: Uses basic regex-based sanitization for Cloudflare Workers compatibility
|
||||||
|
* DOMPurify doesn't work in Workers due to lack of DOM APIs
|
||||||
*/
|
*/
|
||||||
import DOMPurify from 'isomorphic-dompurify'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic SVG sanitization for environments without DOM
|
* SVG sanitization - removes dangerous tags and attributes
|
||||||
* Removes dangerous tags and attributes
|
* Suitable for Cloudflare Workers environment
|
||||||
*/
|
|
||||||
const basicSanitize = (svg: string): string => {
|
|
||||||
// Remove script tags and their content
|
|
||||||
let sanitized = svg.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
|
|
||||||
// Remove dangerous attributes
|
|
||||||
sanitized = sanitized.replace(/\s*on\w+\s*=\s*["'][^"']*["']/gi, '')
|
|
||||||
// Remove other dangerous tags
|
|
||||||
sanitized = sanitized.replace(/<(iframe|object|embed|style)[^>]*>.*?<\/\1>/gi, '')
|
|
||||||
return sanitized
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sanitize SVG content to prevent XSS attacks
|
|
||||||
* Only allows safe SVG elements and attributes
|
|
||||||
*/
|
*/
|
||||||
export const sanitizeSvg = (svg: string): string => {
|
export const sanitizeSvg = (svg: string): string => {
|
||||||
// Check if DOMPurify is available (has sanitize method)
|
if (!svg || typeof svg !== 'string') {
|
||||||
if (typeof DOMPurify?.sanitize === 'function') {
|
return ''
|
||||||
try {
|
|
||||||
return DOMPurify.sanitize(svg, {
|
|
||||||
USE_PROFILES: { svg: true, svgFilters: true },
|
|
||||||
ADD_TAGS: ['use', 'defs', 'symbol'],
|
|
||||||
ADD_ATTR: [
|
|
||||||
'viewBox',
|
|
||||||
'fill',
|
|
||||||
'class',
|
|
||||||
'stroke',
|
|
||||||
'stroke-width',
|
|
||||||
'd',
|
|
||||||
'cx',
|
|
||||||
'cy',
|
|
||||||
'r',
|
|
||||||
'x',
|
|
||||||
'y',
|
|
||||||
'width',
|
|
||||||
'height',
|
|
||||||
'transform',
|
|
||||||
'xmlns',
|
|
||||||
'xmlns:xlink',
|
|
||||||
'xlink:href',
|
|
||||||
'preserveAspectRatio',
|
|
||||||
'clip-rule',
|
|
||||||
'fill-rule',
|
|
||||||
],
|
|
||||||
FORBID_TAGS: ['script', 'iframe', 'object', 'embed', 'style'],
|
|
||||||
FORBID_ATTR: ['onload', 'onerror', 'onclick', 'onmouseover'],
|
|
||||||
})
|
|
||||||
} catch {
|
|
||||||
// Fallback to basic sanitization if DOMPurify fails
|
|
||||||
return basicSanitize(svg)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Fallback for non-browser environments (Cloudflare Workers)
|
|
||||||
return basicSanitize(svg)
|
let sanitized = svg
|
||||||
|
|
||||||
|
// Remove script tags and their content
|
||||||
|
sanitized = sanitized.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
|
||||||
|
|
||||||
|
// Remove dangerous tags and their content
|
||||||
|
sanitized = sanitized.replace(/<(iframe|object|embed|style|link|meta|base)[^>]*>.*?<\/\1>/gi, '')
|
||||||
|
sanitized = sanitized.replace(/<(iframe|object|embed|style|link|meta|base)[^>]*\/?>/gi, '')
|
||||||
|
|
||||||
|
// Remove event handlers (onclick, onload, onerror, etc.)
|
||||||
|
sanitized = sanitized.replace(/\s+on\w+\s*=\s*["'][^"']*["']/gi, '')
|
||||||
|
sanitized = sanitized.replace(/\s+on\w+\s*=\s*[^\s>]+/gi, '')
|
||||||
|
|
||||||
|
// Remove javascript: URLs
|
||||||
|
sanitized = sanitized.replace(/javascript\s*:/gi, '')
|
||||||
|
|
||||||
|
// Remove data: URLs (except for images which are safe in SVGs)
|
||||||
|
sanitized = sanitized.replace(/(?<!image\/)data\s*:/gi, '')
|
||||||
|
|
||||||
|
// Remove style attributes that could contain expressions
|
||||||
|
sanitized = sanitized.replace(/\s+style\s*=\s*["'][^"']*expression[^"']*["']/gi, '')
|
||||||
|
|
||||||
|
return sanitized
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user