mirror of
https://github.com/discourse/discourse.git
synced 2026-08-08 14:34:02 +08:00
## Summary TopicEmbed.imported_from_html interpolated a URL-normalized value directly into a single-quoted href attribute and display text. URL normalization preserves apostrophes, allowing a crafted embed URL to inject an HTML event-handler attribute into the companion footer. The fix applies HTML escaping after URL normalization, preventing the value from breaking out of its attribute or text contexts. Both the import and expand embed paths are covered because they share the same generated footer. ## Source - Patch Triage: https://patch.discourse.org/patch-triage/1544
31 lines
1 KiB
Ruby
Vendored
31 lines
1 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
RSpec.describe "Imported topic embeds" do
|
|
fab!(:embeddable_host) { Fabricate(:embeddable_host, host: "eviltrout.com") }
|
|
|
|
let(:embed_url) { "http://eviltrout.com/'onmouseover='window.topicEmbedXssExecuted=true" }
|
|
|
|
before do
|
|
SiteSetting.content_security_policy = false
|
|
SiteSetting.import_embed_unlisted = false
|
|
Jobs.run_immediately!
|
|
stub_request(:get, embed_url).to_return(
|
|
status: 200,
|
|
body: "<html><title>Embedded article</title><body><p>Article content</p></body></html>",
|
|
)
|
|
end
|
|
|
|
it "does not execute JavaScript from an imported URL" do
|
|
visit("/embed/comments?#{{ embed_url: embed_url }.to_query}")
|
|
expect(page).to have_content(I18n.t("embed.loading"))
|
|
|
|
visit(TopicEmbed.last.post.topic.url)
|
|
link = find("#post_1 .cooked a", text: embed_url)
|
|
|
|
page.execute_script("window.topicEmbedXssExecuted = false")
|
|
link.hover
|
|
|
|
expect(page.evaluate_script("window.topicEmbedXssExecuted")).to eq(false)
|
|
expect(link["onmouseover"]).to be_nil
|
|
end
|
|
end
|