From 84f7fc562c0ec2fe51775277ba83fe75b6ad03de Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Wed, 9 Apr 2025 21:11:27 +0300 Subject: [PATCH 1/3] CSP form-action self --- application/Espo/Core/Utils/ClientManager.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/application/Espo/Core/Utils/ClientManager.php b/application/Espo/Core/Utils/ClientManager.php index 48a576b5d9..f59d9fa272 100644 --- a/application/Espo/Core/Utils/ClientManager.php +++ b/application/Espo/Core/Utils/ClientManager.php @@ -112,6 +112,10 @@ class ClientManager $string .= ' ' . $src; } + if (!$this->config->get('clientCspFormActionDisabled')) { + $string .= "; form-action 'self'"; + } + // Checking the parameter for bc. if (!$this->config->get('clientXFrameOptionsHeaderDisabled')) { $string .= '; frame-ancestors'; From 6b58d30eec8864de52844bfb8dac346ce5c729d7 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Wed, 9 Apr 2025 21:19:39 +0300 Subject: [PATCH 2/3] improve html sanitize --- client/src/view-helper.js | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/client/src/view-helper.js b/client/src/view-helper.js index 12d931e763..9595cfcc86 100644 --- a/client/src/view-helper.js +++ b/client/src/view-helper.js @@ -77,6 +77,22 @@ class ViewHelper { if (node instanceof HTMLOListElement && node.start && node.start > 99) { node.removeAttribute('start'); } + + if (node instanceof HTMLFormElement) { + if (node.action) { + node.removeAttribute('action'); + } + + if (node.hasAttribute('method')) { + node.removeAttribute('method'); + } + } + + if (node instanceof HTMLButtonElement) { + if (node.type === 'submit') { + node.type = 'button'; + } + } }); DOMPurify.addHook('afterSanitizeAttributes', function (node) { @@ -93,6 +109,29 @@ class ViewHelper { } } }); + + DOMPurify.addHook('uponSanitizeAttribute', (node, data) => { + if (data.attrName === 'style') { + const style = data.attrValue + .split(';') + .map(s => s.trim()) + .filter(rule => { + const [property, value] = rule.split(':') + .map(s => s.trim().toLowerCase()); + + if ( + property === 'position' && + ['absolute', 'fixed', 'sticky'].includes(value) + ) { + return false; + } + + return true; + }); + + data.attrValue = style.join('; '); + } + }); } /** From 61c5ad98026a6a05fdbbd6135f0cd01245c449e6 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Wed, 9 Apr 2025 21:54:03 +0300 Subject: [PATCH 3/3] email show body plain impr --- client/src/views/email/modals/body-plain.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/client/src/views/email/modals/body-plain.js b/client/src/views/email/modals/body-plain.js index 10640cabc7..0977b71f36 100644 --- a/client/src/views/email/modals/body-plain.js +++ b/client/src/views/email/modals/body-plain.js @@ -32,7 +32,14 @@ export default class extends ModalView { backdrop = true - templateContent = `
{{{bodyPlain}}}
` + templateContent = ` +
+
+
{{{bodyPlain}}}
+
+ +
+ ` setup() { super.setup(); @@ -52,6 +59,7 @@ export default class extends ModalView { params: { readOnly: true, inlineEditDisabled: true, + displayRawText: true, }, }, });