From: Tom Hughes Date: Tue, 7 Nov 2023 10:31:57 +0000 (+0000) Subject: Strengthen the tokens used in email reply addresses X-Git-Tag: live~977 X-Git-Url: https://git.openstreetmap.org./rails.git/commitdiff_plain/675b89ddb7f3c93ced3e6e1fed2db2caca4d67e4 Strengthen the tokens used in email reply addresses --- diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index a9c6b70f9..89f8dfdbf 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -81,7 +81,7 @@ class UserMailer < ApplicationMailer attach_user_avatar(message.sender) - mail :from => from_address(message.sender.display_name, "m", message.id, message.digest), + mail :from => from_address(message.sender.display_name, "m", message.id, message.notification_token), :to => message.recipient.email, :subject => t(".subject", :message_title => message.title) end @@ -102,7 +102,7 @@ class UserMailer < ApplicationMailer set_references("diary", comment.diary_entry) - mail :from => from_address(comment.user.display_name, "c", comment.id, comment.digest, recipient.id), + mail :from => from_address(comment.user.display_name, "c", comment.id, comment.notification_token(recipient.id), recipient.id), :to => recipient.email, :subject => t(".subject", :user => comment.user.display_name) end @@ -225,12 +225,12 @@ class UserMailer < ApplicationMailer I18n.with_locale(Locale.available.preferred(recipient.preferred_languages), &block) end - def from_address(name, type, id, digest, user_id = nil) + def from_address(name, type, id, token, user_id = nil) if Settings.key?(:messages_domain) && domain = Settings.messages_domain if user_id - "#{name} <#{type}-#{id}-#{user_id}-#{digest[0, 6]}@#{domain}>" + "#{name} <#{type}-#{id}-#{user_id}-#{token}@#{domain}>" else - "#{name} <#{type}-#{id}-#{digest[0, 6]}@#{domain}>" + "#{name} <#{type}-#{id}-#{token}@#{domain}>" end else Settings.email_from diff --git a/app/models/diary_comment.rb b/app/models/diary_comment.rb index 05f5044c5..8663212eb 100644 --- a/app/models/diary_comment.rb +++ b/app/models/diary_comment.rb @@ -37,13 +37,12 @@ class DiaryComment < ApplicationRecord RichText.new(self[:body_format], self[:body]) end - def digest - md5 = Digest::MD5.new - md5 << diary_entry_id.to_s - md5 << user_id.to_s - md5 << created_at.xmlschema - md5 << body - md5.hexdigest + def notification_token(subscriber) + sha256 = Digest::SHA256.new + sha256 << Rails.application.key_generator.generate_key("openstreetmap/diary_comment") + sha256 << id.to_s + sha256 << subscriber.to_s + sha256.base64digest[0, 8] end private diff --git a/app/models/message.rb b/app/models/message.rb index 49c11e900..0068bc3de 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -59,13 +59,10 @@ class Message < ApplicationRecord RichText.new(self[:body_format], self[:body]) end - def digest - md5 = Digest::MD5.new - md5 << from_user_id.to_s - md5 << to_user_id.to_s - md5 << sent_on.xmlschema - md5 << title - md5 << body - md5.hexdigest + def notification_token + sha256 = Digest::SHA256.new + sha256 << Rails.application.key_generator.generate_key("openstreetmap/message") + sha256 << id.to_s + sha256.base64digest[0, 8] end end diff --git a/script/deliver-message b/script/deliver-message index 087a117c3..28d755b24 100755 --- a/script/deliver-message +++ b/script/deliver-message @@ -4,14 +4,14 @@ require File.join(File.dirname(__FILE__), "..", "config", "environment") if recipient = ARGV[0].match(/^c-(\d+)-(\d+)-(.*)$/) comment = DiaryComment.find(recipient[1]) - digest = comment.digest + expected_token = comment.notification_token(recipient[2]) date = comment.created_at from = comment.diary_entry.subscribers.find(recipient[2]) to = comment.user token = recipient[3] elsif recipient = ARGV[0].match(/^m-(\d+)-(.*)$/) message = Message.find(recipient[1]) - digest = message.digest + expected_token = message.notification_token date = message.sent_on from = message.recipient to = message.sender @@ -20,7 +20,7 @@ else exit 0 end -exit 0 unless ActiveSupport::SecurityUtils.secure_compare(token, digest[0, 6]) +exit 0 unless ActiveSupport::SecurityUtils.secure_compare(token, expected_token) exit 0 unless from.active? exit 0 if date < 1.month.ago