aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/rails
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2019-03-10 16:37:46 -0700
committerJohn Hawthorn <john@hawthorn.email>2019-03-10 21:30:03 -0700
commit4c743587ad6a31908503ab317e37d70361d49e66 (patch)
treedea618c58eb9c761555d60d20030372c1ecc3131 /railties/lib/rails
parentf4c70c2222180b8d9d924f00af0c7fd632e26715 (diff)
downloadrails-4c743587ad6a31908503ab317e37d70361d49e66.tar.gz
rails-4c743587ad6a31908503ab317e37d70361d49e66.tar.bz2
rails-4c743587ad6a31908503ab317e37d70361d49e66.zip
Fix possible dev mode RCE
If the secret_key_base is nil in dev or test generate a key from random bytes and store it in a tmp file. This prevents the app developers from having to share / checkin the secret key for dev / test but also maintains a key between app restarts in dev/test. [CVE-2019-5420] Co-Authored-By: eileencodes <eileencodes@gmail.com> Co-Authored-By: John Hawthorn <john@hawthorn.email>
Diffstat (limited to 'railties/lib/rails')
-rw-r--r--railties/lib/rails/application.rb19
1 files changed, 17 insertions, 2 deletions
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index fbad3e5db3..558a4d1f57 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -415,8 +415,8 @@ module Rails
# then credentials.secret_key_base, and finally secrets.secret_key_base. For most applications,
# the correct place to store it is in the encrypted credentials file.
def secret_key_base
- if Rails.env.test? || Rails.env.development?
- secrets.secret_key_base || Digest::MD5.hexdigest(self.class.name)
+ if Rails.env.development? || Rails.env.test?
+ secrets.secret_key_base ||= generate_development_secret
else
validate_secret_key_base(
ENV["SECRET_KEY_BASE"] || credentials.secret_key_base || secrets.secret_key_base
@@ -581,6 +581,21 @@ module Rails
private
+ def generate_development_secret
+ if secrets.secret_key_base.nil?
+ key_file = Rails.root.join("tmp/development_secret.txt")
+
+ if !File.exist?(key_file)
+ random_key = SecureRandom.hex(64)
+ File.binwrite(key_file, random_key)
+ end
+
+ secrets.secret_key_base = File.binread(key_file)
+ end
+
+ secrets.secret_key_base
+ end
+
def build_request(env)
req = super
env["ORIGINAL_FULLPATH"] = req.fullpath