mirror of
https://github.com/root-fr/jmap-webmail.git
synced 2026-10-01 08:00:26 +00:00
fix(security): escape linkClassName in plainTextToSafeHtml
Defense-in-depth. All current callers pass hardcoded tailwind class strings, so this is not exploitable today, but a future caller that forwarded a user-controlled value would get HTML injection through the class attribute. Run the value through escapeHtml() and add a test covering the attribute-escape case.
This commit is contained in:
@@ -287,6 +287,15 @@ describe('email-sanitization', () => {
|
||||
expect(html).toContain('class="text-primary hover:underline"');
|
||||
});
|
||||
|
||||
it('escapes linkClassName to defend against a caller-supplied injection', () => {
|
||||
const malicious = 'x" onfocus="alert(1)" x="';
|
||||
const html = plainTextToSafeHtml('https://x.test', { linkClassName: malicious });
|
||||
const a = parseAnchor(html);
|
||||
expect(a).not.toBeNull();
|
||||
expect(a!.getAttribute('onfocus')).toBeNull();
|
||||
expect(a!.className).toContain('onfocus=');
|
||||
});
|
||||
|
||||
it('preserves line breaks and tabs', () => {
|
||||
const html = plainTextToSafeHtml('a\nb\tc\r\nd');
|
||||
expect(html).toContain('a<br>b c<br>d');
|
||||
|
||||
@@ -123,7 +123,7 @@ export function plainTextToSafeHtml(
|
||||
options?: { linkClassName?: string }
|
||||
): string {
|
||||
const linkClass = options?.linkClassName
|
||||
? ` class="${options.linkClassName}"`
|
||||
? ` class="${escapeHtml(options.linkClassName)}"`
|
||||
: '';
|
||||
return escapeHtml(text)
|
||||
.replace(/\r\n/g, '<br>')
|
||||
|
||||
Reference in New Issue
Block a user