From c85cc667ebfd3c270df37c7575d580ea6462e12f Mon Sep 17 00:00:00 2001
From: Aaron Patterson <aaron@rubyonrails.org>
Date: Tue, 22 Aug 2023 09:58:43 -0700
Subject: [PATCH] Use a temporary file for storing unencrypted files while
 editing

Refer: https://github.com/rails/rails/commit/c85cc667ebfd3c270df37c7575d580ea6462e12f

When we're editing the contents of encrypted files, we should use the
`Tempfile` class because it creates temporary files with restrictive
permissions.  This prevents other users on the same system from reading
the contents of those files while the user is editing them.

[CVE-2023-38037]

---
 lib/active_support/encrypted_file.rb | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/lib/active_support/encrypted_file.rb b/lib/active_support/encrypted_file.rb
index c66f1b5..cb63e6e 100644
--- a/lib/active_support/encrypted_file.rb
+++ b/lib/active_support/encrypted_file.rb
@@ -1,6 +1,7 @@
 # frozen_string_literal: true
 
 require "pathname"
+require "tempfile"
 require "active_support/message_encryptor"
 
 module ActiveSupport
@@ -57,17 +58,16 @@ module ActiveSupport
 
     private
       def writing(contents)
-        tmp_file = "#{Process.pid}.#{content_path.basename.to_s.chomp('.enc')}"
-        tmp_path = Pathname.new File.join(Dir.tmpdir, tmp_file)
-        tmp_path.binwrite contents
+        Tempfile.create(["", "-" + content_path.basename.to_s.chomp(".enc")]) do |tmp_file|
+          tmp_path = Pathname.new(tmp_file)
+          tmp_path.binwrite contents
 
-        yield tmp_path
+          yield tmp_path
 
-        updated_contents = tmp_path.binread
+          updated_contents = tmp_path.binread
 
-        write(updated_contents) if updated_contents != contents
-      ensure
-        FileUtils.rm(tmp_path) if tmp_path.exist?
+          write(updated_contents) if updated_contents != contents
+        end
       end
 
 
-- 
2.33.0

