import { describe, it, expect } from 'vitest';
import { Window } from 'happy-dom';
import { formatValue } from '../../src/info-panel/ValueFormatter';
import { escapeHtml, sanitizeElement } from '../../src/shared/utils';
describe('Security', () => {
describe('sanitizeElement', () => {
it('should remove event handlers from an element', () => {
const window = new Window();
const document = window.document;
const element = document.createElement('div');
element.setAttribute('onclick', 'alert(1)');
element.setAttribute('onerror', 'alert(1)');
element.setAttribute('onload', 'alert(1)');
element.setAttribute('class', 'safe');
sanitizeElement(element as unknown as HTMLElement);
expect(element.hasAttribute('onclick')).toBe(false);
expect(element.hasAttribute('onerror')).toBe(false);
expect(element.hasAttribute('onload')).toBe(false);
expect(element.getAttribute('class')).toBe('safe');
});
it('should recursively remove event handlers from children', () => {
const window = new Window();
const document = window.document;
const parent = document.createElement('div');
const child = document.createElement('img');
child.setAttribute('src', 'x');
child.setAttribute('onerror', 'alert(1)');
parent.appendChild(child);
sanitizeElement(parent as unknown as HTMLElement);
expect(child.hasAttribute('onerror')).toBe(false);
expect(child.getAttribute('src')).toBe('x');
});
it('should remove javascript: URIs from dangerous attributes', () => {
const window = new Window();
const document = window.document;
const link = document.createElement('a');
const img = document.createElement('img');
const form = document.createElement('form');
link.setAttribute('href', 'javascript:alert(1)');
img.setAttribute('src', 'javascript:alert(1)');
form.setAttribute('action', 'javascript:alert(1)');
form.setAttribute('formaction', 'javascript:alert(1)');
sanitizeElement(link as unknown as HTMLElement);
sanitizeElement(img as unknown as HTMLElement);
sanitizeElement(form as unknown as HTMLElement);
expect(link.hasAttribute('href')).toBe(false);
expect(img.hasAttribute('src')).toBe(false);
expect(form.hasAttribute('action')).toBe(false);
expect(form.hasAttribute('formaction')).toBe(false);
});
it('should remove obscured javascript: URIs (whitespace bypass)', () => {
const window = new Window();
const document = window.document;
const link = document.createElement('a');
// Bypass attempts: tabs, newlines, spaces
link.setAttribute('href', 'java\tscript:alert(1)');
sanitizeElement(link as unknown as HTMLElement);
expect(link.hasAttribute('href')).toBe(false);
link.setAttribute('href', 'java\nscript:alert(1)');
sanitizeElement(link as unknown as HTMLElement);
expect(link.hasAttribute('href')).toBe(false);
link.setAttribute('href', ' javascript:alert(1)');
sanitizeElement(link as unknown as HTMLElement);
expect(link.hasAttribute('href')).toBe(false);
});
it('should preserve safe URLs', () => {
const window = new Window();
const document = window.document;
const link = document.createElement('a');
link.setAttribute('href', 'https://example.com');
sanitizeElement(link as unknown as HTMLElement);
expect(link.getAttribute('href')).toBe('https://example.com');
});
it('should handle elements without attributes gracefully', () => {
const window = new Window();
const document = window.document;
const element = document.createElement('div');
// Should not throw
sanitizeElement(element as unknown as HTMLElement);
expect(true).toBe(true);
});
it('should handle null/undefined gracefully', () => {
// Should not throw
sanitizeElement(null as any);
sanitizeElement(undefined as any);
expect(true).toBe(true);
});
});
describe('formatValue', () => {
it('should escape HTML in values to prevent XSS', () => {
const maliciousInput = '';
const escaped = formatValue(maliciousInput);
// Assert that the output does NOT contain the raw script tag
expect(escaped).not.toContain('',
isHtml: true, // This flag should be IGNORED now
label: 'Malicious Button'
};
const renderedValue = renderItem(item);
// It should fall through to formatValue which escapes
expect(renderedValue).not.toContain('',
specialType: 'focus-node',
label: 'Location'
};
const renderedValue = renderItem(item);
// The container span is there
expect(renderedValue).toContain('');
// But the content is escaped
expect(renderedValue).not.toContain('',
isHtml: false,
label: 'Malicious Input'
};
const renderedValue = renderItem(item);
expect(renderedValue).not.toContain('