]> git.openstreetmap.org Git - rails.git/commitdiff
Strengthen the tokens used in email reply addresses
authorTom Hughes <tom@compton.nu>
Tue, 7 Nov 2023 10:31:57 +0000 (10:31 +0000)
committerTom Hughes <tom@compton.nu>
Tue, 7 Nov 2023 17:52:31 +0000 (17:52 +0000)
app/mailers/user_mailer.rb
app/models/diary_comment.rb
app/models/message.rb
script/deliver-message

index a9c6b70f91eeb29d8538aa1c18859e199a38b8ad..89f8dfdbf781e66bb20533f2de5db71112e3ff85 100644 (file)
@@ -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
index 05f5044c5db779b232da81bd6e3bbdf0ba31d5b5..8663212ebeef93a38dbd0ce7399f09e975ebfb04 100644 (file)
@@ -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
index 49c11e900898923beb558d78d8d2b6e35845a158..0068bc3de504ee2d7e380cc2641b4ae1889082ba 100644 (file)
@@ -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
index 087a117c3dceeeba884d600e8107de05aa77d950..28d755b24d4a40e74934d50600258764234d5803 100755 (executable)
@@ -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