fix: allow table-based layouts in HTML signature sanitizer

This commit is contained in:
Linus Rath
2026-05-18 00:24:08 +02:00
parent be5ff96e4d
commit 92127e2f00
2 changed files with 29 additions and 8 deletions
+18 -5
View File
@@ -168,19 +168,32 @@ describe('email-sanitization', () => {
expect(sanitizeSignatureHtml(' ')).toBe('');
});
it('should be stricter than email sanitization', () => {
const html = '<p>Text</p><table><tr><td>Data</td></tr></table><video src="v.mp4"></video>';
it('should be stricter than email sanitization for script-bearing tags', () => {
const html = '<p>Text</p><table><tr><td>Data</td></tr></table><video src="v.mp4"></video><iframe src="x"></iframe>';
const emailClean = sanitizeEmailHtml(html);
const signatureClean = sanitizeSignatureHtml(html);
// Email allows table
// Both preserve tables (signatures are universally table-based)
expect(emailClean).toContain('<table>');
expect(signatureClean).toContain('<table');
expect(signatureClean).toContain('Data');
// Signature blocks table and video
expect(signatureClean).not.toContain('<table');
// Signature still blocks media and frames
expect(signatureClean).not.toContain('<video');
expect(signatureClean).not.toContain('<iframe');
expect(signatureClean).toContain('Text');
});
it('should preserve table layout attributes used by email signatures', () => {
const signature = '<table cellpadding="0" cellspacing="0" border="0"><tr><td valign="top" align="left" bgcolor="#fafafa" colspan="2">Name</td></tr></table>';
const clean = sanitizeSignatureHtml(signature);
expect(clean).toContain('cellpadding');
expect(clean).toContain('cellspacing');
expect(clean).toContain('valign');
expect(clean).toContain('align');
expect(clean).toContain('bgcolor');
expect(clean).toContain('colspan');
});
});
describe('parseHtmlSafely', () => {
+11 -3
View File
@@ -58,11 +58,19 @@ export function sanitizeEmailHtmlForIframe(html: string): string {
/**
* Sanitize HTML signature with stricter rules
* Allows basic formatting plus <img> for company logos
* Allows basic formatting plus <img> for company logos, plus table-based
* layouts (the de-facto standard for email signatures).
*/
export const SIGNATURE_SANITIZE_CONFIG = {
ALLOWED_TAGS: ['p', 'br', 'b', 'strong', 'i', 'em', 'u', 'a', 'span', 'div', 'img'],
ALLOWED_ATTR: ['href', 'style', 'class', 'src', 'alt', 'width', 'height', 'title'],
ALLOWED_TAGS: [
'p', 'br', 'b', 'strong', 'i', 'em', 'u', 'a', 'span', 'div', 'img',
'table', 'thead', 'tbody', 'tfoot', 'tr', 'td', 'th',
],
ALLOWED_ATTR: [
'href', 'style', 'class', 'src', 'alt', 'width', 'height', 'title',
'cellpadding', 'cellspacing', 'border', 'valign', 'align', 'bgcolor',
'colspan', 'rowspan',
],
ALLOW_DATA_ATTR: false,
FORBID_TAGS: ['script', 'iframe', 'object', 'embed', 'video', 'audio'],
FORBID_ATTR: ['onerror', 'onload', 'onclick', 'onmouseover'],