Improved handling of secure message <style> CSS class names

This commit is contained in:
the-djmaze 2023-02-14 15:21:43 +01:00
parent 64818025e8
commit 5105f6d4c1
3 changed files with 22 additions and 19 deletions

View file

@ -27,11 +27,13 @@ export class CSS
* Given css array, parses it and then for every selector, * Given css array, parses it and then for every selector,
* prepends namespace to prevent css collision issues * prepends namespace to prevent css collision issues
*/ */
css.applyNamespace = (namespace) => css.forEach(obj => { css.applyNamespace = (namespace, prefix) => css.forEach(obj => {
if (obj.type === 'media') { if (obj.type === 'media') {
obj.subStyles.applyNamespace(namespace); obj.subStyles.applyNamespace(namespace, prefix);
} else { } else {
obj.selector = obj.selector.split(',').map(selector => namespace + ' ' + selector).join(','); obj.selector = obj.selector.split(',').map(selector =>
namespace + ' ' + selector.replace('.', '.'+prefix)
).join(',');
} }
}); });

View file

@ -133,7 +133,7 @@ export const
}, },
allowedAttributes = [ allowedAttributes = [
// defaults // defaults
'name', 'class', 'name',
'dir', 'lang', 'style', 'title', 'dir', 'lang', 'style', 'title',
'background', 'bgcolor', 'alt', 'height', 'width', 'src', 'href', 'background', 'bgcolor', 'alt', 'height', 'width', 'src', 'href',
'border', 'bordercolor', 'charset', 'direction', 'border', 'bordercolor', 'charset', 'direction',
@ -171,6 +171,12 @@ export const
'A','B','EM','I','SPAN','STRONG' 'A','B','EM','I','SPAN','STRONG'
]; ];
if (SettingsUserStore.allowStyles()) {
allowedAttributes.push('class');
} else {
msgId = 0;
}
tpl.innerHTML = html tpl.innerHTML = html
// Strip Microsoft comments // Strip Microsoft comments
.replace(/<!--\[if[\s\S]*?endif\]-->/gi, '') .replace(/<!--\[if[\s\S]*?endif\]-->/gi, '')
@ -205,8 +211,11 @@ export const
if ('STYLE' === name) { if ('STYLE' === name) {
if (msgId) { if (msgId) {
let css = new CSS().parse(oElement.textContent); let css = new CSS().parse(oElement.textContent);
css.applyNamespace(msgId); css.applyNamespace(msgId, 'msg-');
oElement.textContent = css; oElement.textContent = css;
if (SettingsUserStore.removeColors()) {
oElement.textContent = oElement.textContent.replace(/(background-)color:[^};]+/g, '');
}
} else { } else {
oElement.remove(); oElement.remove();
} }
@ -225,29 +234,23 @@ export const
oElement.remove(); oElement.remove();
return; return;
} }
/*
// Idea to allow CSS
if ('STYLE' === name) {
msgId = '#rl-msg-061eb4d647771be4185943ce91f0039d';
oElement.textContent = oElement.textContent
.replace(/[^{}]+{/g, m => msgId + ' ' + m.replace(',', ', '+msgId+' '))
.replace(/(background-)color:[^};]+/g, '');
return;
}
*/
const aAttrsForRemove = [], const aAttrsForRemove = [],
className = oElement.className,
hasAttribute = name => oElement.hasAttribute(name), hasAttribute = name => oElement.hasAttribute(name),
getAttribute = name => hasAttribute(name) ? oElement.getAttribute(name).trim() : '', getAttribute = name => hasAttribute(name) ? oElement.getAttribute(name).trim() : '',
setAttribute = (name, value) => oElement.setAttribute(name, value), setAttribute = (name, value) => oElement.setAttribute(name, value),
delAttribute = name => oElement.removeAttribute(name); delAttribute = name => oElement.removeAttribute(name);
if ('mail-body' === oElement.className) { if ('mail-body' === className) {
forEachObjectEntry(tasks, (name, cb) => { forEachObjectEntry(tasks, (name, cb) => {
if (hasAttribute(name)) { if (hasAttribute(name)) {
cb(getAttribute(name), oElement); cb(getAttribute(name), oElement);
delAttribute(name); delAttribute(name);
} }
}); });
} else if (msgId && className) {
oElement.className = className.replace(/(^|\s+)/g, '$1msg-');
} }
if (oElement.hasAttributes()) { if (oElement.hasAttributes()) {

View file

@ -25,9 +25,7 @@ import { LanguageStore } from 'Stores/Language';
import Remote from 'Remote/User/Fetch'; import Remote from 'Remote/User/Fetch';
const const
msgHtml = msg => cleanHtml(msg.html(), msg.attachments(), msgHtml = msg => cleanHtml(msg.html(), msg.attachments(), '#rl-msg-' + msg.hash),
SettingsUserStore.allowStyles() ? '#rl-msg-' + msg.hash : ''
),
toggleTag = (message, keyword) => { toggleTag = (message, keyword) => {
const lower = keyword.toLowerCase(), const lower = keyword.toLowerCase(),