From 1ec52306a250bd9c4034ab62b6dac500fceabc24 Mon Sep 17 00:00:00 2001
From: Moshi <54333972+MoshiKoi@users.noreply.github.com>
Date: Fri, 11 Aug 2023 02:13:54 -0700
Subject: [PATCH 1/4] Add notice when tags and attributes are rejected
---
app/assets/javascripts/posts.js | 21 +++++++++++++++++++++
app/views/posts/_form.html.erb | 8 ++++++++
2 files changed, 29 insertions(+)
diff --git a/app/assets/javascripts/posts.js b/app/assets/javascripts/posts.js
index 25c0fe65a..a30edb3d6 100644
--- a/app/assets/javascripts/posts.js
+++ b/app/assets/javascripts/posts.js
@@ -149,6 +149,27 @@ $(() => {
ALLOWED_TAGS,
ALLOWED_ATTR
});
+
+ const removedElements = [...new Set(DOMPurify.removed
+ .filter(entry => entry.element && !(entry.element instanceof HTMLBodyElement))
+ .map(entry => entry.element.localName))];
+
+ const removedAttributes = [...new Set(DOMPurify.removed
+ .filter(entry => entry.attribute)
+ .map(entry => [
+ entry.attribute.name + (entry.attribute.value ? `='${entry.attribute.value}'` : ''),
+ entry.from.localName
+ ]))]
+
+ $tgt.parents('form')
+ .find('.rejected-elements')
+ .toggleClass('hide', removedElements.length === 0)
+ .find('ul')
+ .empty()
+ .append(
+ removedElements.map(name => $(`
<${name}>
`)),
+ removedAttributes.map(([attr, elName]) => $(`${attr}
(in <${elName}>
)`)));
+
$tgt.parents('.form-group').siblings('.post-preview').html(html);
$tgt.parents('form').find('.js-post-html[name="__html"]').val(html + '');
}, 0);
diff --git a/app/views/posts/_form.html.erb b/app/views/posts/_form.html.erb
index 47a8eaf77..40c533cb5 100644
--- a/app/views/posts/_form.html.erb
+++ b/app/views/posts/_form.html.erb
@@ -57,6 +57,14 @@
<%= render 'shared/body_field', f: f, field_name: :body_markdown, field_label: t('posts.body_label'), post: post,
min_length: min_body_length(category), max_length: max_body_length(category) %>
+
+
Unsupported HTML detected
+
The following HTML tags and attributes are unsupported and will be removed from the final post:
+
+
For a list of allowed HTML, see this Meta post.
+ If you meant to display the tags as code in the post, please enclose them in a code block.
+
<% unless post_type.has_parent? %>
From 27d8d77383418b75f1f479969c46ae3301130ef6 Mon Sep 17 00:00:00 2001
From: Moshi <54333972+MoshiKoi@users.noreply.github.com>
Date: Wed, 4 Oct 2023 18:16:25 -0700
Subject: [PATCH 2/4] Link to help article
---
app/views/posts/_form.html.erb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/posts/_form.html.erb b/app/views/posts/_form.html.erb
index 40c533cb5..92a345698 100644
--- a/app/views/posts/_form.html.erb
+++ b/app/views/posts/_form.html.erb
@@ -62,7 +62,7 @@
The following HTML tags and attributes are unsupported and will be removed from the final post:
- For a list of allowed HTML, see this Meta post.
+
For a list of allowed HTML, see this help article.
If you meant to display the tags as code in the post, please enclose them in a code block.
From 5994e09df260561498d7143e92ebf65f5238723c Mon Sep 17 00:00:00 2001
From: Oleg Valter
Date: Sun, 22 Oct 2023 02:25:54 +0300
Subject: [PATCH 3/4] fix .rejected-elements container staying hidden on no
removed elements but some removed attributes
---
app/assets/javascripts/posts.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/assets/javascripts/posts.js b/app/assets/javascripts/posts.js
index a30edb3d6..365aacce7 100644
--- a/app/assets/javascripts/posts.js
+++ b/app/assets/javascripts/posts.js
@@ -163,7 +163,7 @@ $(() => {
$tgt.parents('form')
.find('.rejected-elements')
- .toggleClass('hide', removedElements.length === 0)
+ .toggleClass('hide', removedElements.length === 0 && removedAttributes.length === 0)
.find('ul')
.empty()
.append(
From 7bbf18b5c0048d0c6406e9ab64bcc8ebac7f4c69 Mon Sep 17 00:00:00 2001
From: Oleg Valter
Date: Sun, 22 Oct 2023 03:03:52 +0300
Subject: [PATCH 4/4] add rowspan / colspan attribute validation
---
app/assets/javascripts/posts.js | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/app/assets/javascripts/posts.js b/app/assets/javascripts/posts.js
index 365aacce7..955587c4a 100644
--- a/app/assets/javascripts/posts.js
+++ b/app/assets/javascripts/posts.js
@@ -6,6 +6,19 @@ const ALLOWED_ATTR = ['id', 'class', 'href', 'title', 'src', 'height', 'width',
'start', 'dir'];
$(() => {
+ DOMPurify.addHook("uponSanitizeAttribute", (node, event) => {
+ const rowspan = node.getAttribute("rowspan");
+ const colspan = node.getAttribute("colspan");
+
+ if (rowspan && Number.isNaN(+rowspan)) {
+ event.keepAttr = false;
+ }
+
+ if (colspan && Number.isNaN(+colspan)) {
+ event.keepAttr = false;
+ }
+ });
+
const $uploadForm = $('.js-upload-form');
const stringInsert = (str, idx, insert) => str.slice(0, idx) + insert + str.slice(idx);