diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index b644a289475..7193ead23d0 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -738,6 +738,10 @@ module ApplicationHelper
absolute_url
end
+ def escape_noscript(&block)
+ raw capture(&block).gsub(%r{<(/\s*noscript)}i, '<\1')
+ end
+
def manifest_url
# If you want the `manifest_url` to be different for a specific action,
# in the action set @manifest_url = X. Originally added for chat to add a
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 6777cea56c4..66dc243e230 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -99,15 +99,17 @@
<%= render_google_tag_manager_body_code %>
<%- unless customization_disabled? %>
diff --git a/spec/requests/noscript_escape_spec.rb b/spec/requests/noscript_escape_spec.rb
new file mode 100644
index 00000000000..b76eff22840
--- /dev/null
+++ b/spec/requests/noscript_escape_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+RSpec.describe "escaping of noscript content" do
+ def noscript_content
+ # Browsers do not parse the contents of noscript tags - they just look for the next string matching ``
+ # Can't use nokogiri because it parses documents with the 'scripting flag' disabled, and therefore parses html inside noscript tags
+ noscript_content = response.body.scan(%r{(.*?)}m).join("\n")
+ end
+
+ it "does not affect normal content" do
+ post = Fabricate(:post, raw: 'This is a post with an image ')
+ get post.url
+
+ expect(noscript_content).to include('')
+ end
+
+ it "escapes noscript in attribute" do
+ post =
+ Fabricate(
+ :post,
+ raw: 'This is a post with an image containing a noscript end tag',
+ )
+ get post.url
+
+ expect(noscript_content).to include('')
+ end
+
+ it "escapes noscript with trailing whitespace" do
+ post =
+ Fabricate(
+ :post,
+ raw: 'This is a post with an image containing a noscript end tag',
+ )
+ get post.url
+
+ expect(noscript_content).to include('')
+ end
+
+ it "escapes noscript with leading whitespace" do
+ # The spec doesn't accept closing tags with leading whitespace. Browsers follow that, but some other parsers are more relaxed so we escape anyway
+ post =
+ Fabricate(
+ :post,
+ raw: 'This is a post with an image containing a noscript end tag',
+ )
+ get post.url
+
+ expect(noscript_content).to include('')
+ end
+end