mirror of
https://github.com/discourse/discourse.git
synced 2025-01-16 03:02:43 +08:00
FIX: strip unsubscribe links in incoming emails (#30695)
When we send an email notification to a user, we always include a link that will allow them unsubscribe to these emails. If the user reply to the email notification, the link to unsubscribe might still be present in the final post (often in the elided part). Since those links do not require authentication to unsubscribe a user (this is a feature, not a bug), we would like to avoid showing them to other users on Discourse. (If such an email is forwarded elsewhere, then it's totally out of our control.) This commmit ensures we always strip those unsubscribe links from any incoming email to avoid making it easier to unsubscribe another user. Since the format we use for those links might be similar to the ones used by other applications, the regular expression used to match those links uses the absolute URL of the Discourse (aka. `Discourse.base_url`).
This commit is contained in:
parent
03119312b5
commit
d7aa13328d
|
@ -517,7 +517,12 @@ module Email
|
||||||
.join
|
.join
|
||||||
end
|
end
|
||||||
|
|
||||||
[text, elided_text, text_format]
|
[strip_unsubscribe_links(text), strip_unsubscribe_links(elided_text), text_format]
|
||||||
|
end
|
||||||
|
|
||||||
|
def strip_unsubscribe_links(text)
|
||||||
|
@unsubscribe_regex ||= %r|#{Discourse.base_url}/email/unsubscribe/\h{64}|
|
||||||
|
(text.presence || "").gsub(@unsubscribe_regex, "")
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_markdown(html, elided_html)
|
def to_markdown(html, elided_html)
|
||||||
|
|
|
@ -2268,6 +2268,41 @@ RSpec.describe Email::Receiver do
|
||||||
text, _elided, _format = receiver.select_body
|
text, _elided, _format = receiver.select_body
|
||||||
expect(text).to be_blank
|
expect(text).to be_blank
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "strip unsubscribe links" do
|
||||||
|
keep_relative = "/email/unsubscribe/#{SecureRandom.hex(32)}"
|
||||||
|
keep_other_instance = "http://other.discourse.org/email/unsubscribe/#{SecureRandom.hex(32)}"
|
||||||
|
strip_in_text = "#{Discourse.base_url}/email/unsubscribe/#{SecureRandom.hex(32)}"
|
||||||
|
strip_in_elided = "#{Discourse.base_url}/email/unsubscribe/#{SecureRandom.hex(32)}"
|
||||||
|
|
||||||
|
email = <<~EMAIL
|
||||||
|
Date: Fri, 10 Jan 2024 13:25:42 +0100
|
||||||
|
Subject: Will this be stripped?
|
||||||
|
From: Foo <foo@discourse.org>
|
||||||
|
To: bar@discourse.org
|
||||||
|
Content-Type: text/plain; charset="UTF-8"
|
||||||
|
|
||||||
|
This is a line that will not be touched.
|
||||||
|
|
||||||
|
This is a [relative](#{keep_relative}) link.
|
||||||
|
|
||||||
|
This one is from <a href="#{keep_other_instance}">another instance</a>
|
||||||
|
|
||||||
|
Here's my unsubscribe link: #{strip_in_text}
|
||||||
|
|
||||||
|
XoXo
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
To unsubscribe from these emails, [click here](#{strip_in_elided}).
|
||||||
|
EMAIL
|
||||||
|
|
||||||
|
text, elided, _ = Email::Receiver.new(email).select_body
|
||||||
|
|
||||||
|
expect(text).to_not include(strip_in_text)
|
||||||
|
expect(text).to include(keep_relative, keep_other_instance)
|
||||||
|
expect(elided).to_not include(strip_in_elided)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "replying to digest" do
|
describe "replying to digest" do
|
||||||
|
|
Loading…
Reference in New Issue
Block a user