SECURITY: Block registrations for encoded emails that are invalid

This commit is contained in:
OsamaSayegh 2024-08-27 00:20:37 +03:00 committed by Alan Guo Xiang Tan
parent 34d04e7507
commit d7164d57ec
No known key found for this signature in database
GPG Key ID: 286D2AB58F8C86B6
2 changed files with 37 additions and 5 deletions

View File

@ -1,11 +1,21 @@
# frozen_string_literal: true
class EmailAddressValidator
def self.valid_value?(email)
email.match? email_regex
end
class << self
def valid_value?(email)
email.match?(email_regex) && decode(email)&.match?(email_regex)
end
def self.email_regex
/\A[a-zA-Z0-9!#\$%&'*+\/=?\^_`{|}~\-]+(?:\.[a-zA-Z0-9!#\$%&'\*+\/=?\^_`{|}~\-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?$\z/
def email_regex
/\A[a-zA-Z0-9!#\$%&'*+\/=?\^_`{|}~\-]+(?:\.[a-zA-Z0-9!#\$%&'\*+\/=?\^_`{|}~\-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?$\z/
end
private
def decode(email)
Mail::Address.new(email).decoded
rescue Mail::Field::ParseError, Mail::Field::IncompleteParseError
nil
end
end
end

View File

@ -704,6 +704,28 @@ RSpec.describe UsersController do
end
end
context "when using an encoded email that decodes to an invalid email" do
it "blocks the registration" do
post_user(email: "=?x?q?hacker=40hackerdomain.com=3e=00?=osama@discourseemail.com")
expect(response.status).to eq(200)
expect(response.parsed_body["success"]).to eq(false)
expect(response.parsed_body["message"]).to eq("Primary email is invalid.")
expect(response.parsed_body["user_id"]).to be_blank
end
end
context "when using an encoded email that decodes to a valid email" do
it "accepts the registration" do
post_user(
email:
"=?utf-8?q?=6f=73=61=6d=61=2d=69=6e=2d=71=2d=65=6e=63=6f=64=69=6e=67?=@discourse.org",
)
expect(response.status).to eq(200)
expect(response.parsed_body["success"]).to eq(true)
expect(User.find_by(id: response.parsed_body["user_id"])).to be_present
end
end
context "when creating a user" do
it "sets the user locale to I18n.locale" do
SiteSetting.default_locale = "en"