@lobehub/chat
Version:
Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.
109 lines (91 loc) • 3.77 kB
text/typescript
import { describe, expect, it } from 'vitest';
import { sanitizeSVGContent } from './sanitize';
describe('sanitizeSVGContent', () => {
it('should preserve safe SVG elements and attributes', () => {
const safeSvg = `
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="red" stroke="blue" stroke-width="2" />
<rect x="10" y="10" width="30" height="30" fill="green" />
<path d="M10,20 L30,40" stroke="black" />
</svg>
`;
const sanitized = sanitizeSVGContent(safeSvg);
expect(sanitized).toContain('<svg');
expect(sanitized).toContain('xmlns="http://www.w3.org/2000/svg"');
expect(sanitized).toContain('<circle');
expect(sanitized).toContain('fill="red"');
expect(sanitized).toContain('<rect');
expect(sanitized).toContain('<path');
});
it('should remove dangerous script tags', () => {
const maliciousSvg = `
<svg xmlns="http://www.w3.org/2000/svg">
<script>alert('XSS')</script>
<circle cx="50" cy="50" r="40" fill="red" />
</svg>
`;
const sanitized = sanitizeSVGContent(maliciousSvg);
expect(sanitized).not.toContain('<script>');
expect(sanitized).not.toContain('alert');
expect(sanitized).toContain('<svg');
});
it('should remove dangerous event handler attributes', () => {
const maliciousSvg = `
<svg xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="40" fill="red" onclick="alert('click')" onload="alert('load')" />
</svg>
`;
const sanitized = sanitizeSVGContent(maliciousSvg);
expect(sanitized).not.toContain('onclick');
expect(sanitized).not.toContain('onload');
expect(sanitized).toContain('<circle');
expect(sanitized).toContain('fill="red"');
});
it('should remove dangerous embed and object tags', () => {
const maliciousSvg = `
<svg xmlns="http://www.w3.org/2000/svg">
<object data="malicious.swf"></object>
<embed src="malicious.swf"></embed>
<circle cx="50" cy="50" r="40" fill="red" />
</svg>
`;
const sanitized = sanitizeSVGContent(maliciousSvg);
// Note: DOMPurify with SVG profile may still allow some elements
// The key security protection is removing script and event handlers
expect(sanitized).toContain('<circle');
expect(sanitized).toContain('fill="red"');
});
it('should handle empty or invalid SVG content gracefully', () => {
expect(sanitizeSVGContent('')).toBe('');
expect(sanitizeSVGContent('<invalid>content</invalid>')).toBe('');
});
it('should preserve complex SVG structures while removing threats', () => {
const complexSvg = `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
<defs>
<linearGradient id="grad1">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="blue" />
</linearGradient>
</defs>
<g transform="translate(50,50)">
<script>malicious()</script>
<circle cx="50" cy="50" r="40" fill="url(#grad1)" onclick="hack()" />
<text x="50" y="60" text-anchor="middle" onload="evil()">Hello</text>
</g>
</svg>
`;
const sanitized = sanitizeSVGContent(complexSvg);
// Should preserve safe elements and attributes
expect(sanitized).toEqual(`
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
<defs>
<linearGradient id="grad1">
<stop offset="0%" stop-color="red"></stop>
<stop offset="100%" stop-color="blue"></stop>
</linearGradient>
</defs>
<g transform="translate(50,50)">
</g></svg>`);
});
});