diff options
-rw-r--r-- | guides/source/active_record_querying.md | 2 | ||||
-rw-r--r-- | guides/source/upgrading_ruby_on_rails.md | 2 | ||||
-rw-r--r-- | railties/CHANGELOG.md | 16 | ||||
-rw-r--r-- | railties/lib/rails/commands/secrets/secrets_command.rb | 2 | ||||
-rw-r--r-- | railties/lib/rails/secrets.rb | 21 | ||||
-rw-r--r-- | railties/test/secrets_test.rb | 4 |
6 files changed, 29 insertions, 18 deletions
diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index 31220f9be2..38a9d61f4b 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -1871,7 +1871,7 @@ Which will execute: ```sql SELECT count(DISTINCT clients.id) AS count_all FROM clients - LEFT OUTER JOIN orders ON orders.client_id = client.id WHERE + LEFT OUTER JOIN orders ON orders.client_id = clients.id WHERE (clients.first_name = 'Ryan' AND orders.status = 'received') ``` diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index 6005298127..3afc0e5309 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -80,7 +80,7 @@ It is only soft-deprecated, which means that your code will not break at the moment and no deprecation warning will be displayed but this constant will be removed in the future. -Also, if you have pretty old YAML documents containg dumps of such objects, +Also, if you have pretty old YAML documents containing dumps of such objects, you may need to load and dump them again to make sure that they reference the right constant and that loading them won't break in the future. diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 54bf0ec65e..327b6ab66d 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,3 +1,19 @@ +* Improve encryption for encrypted secrets. + + Switch to aes-128-gcm authenticated encryption. Also generate a random + initialization vector for each encryption so the same input and key can + generate different encrypted data. + + Double the encryption key entropy by properly extracting the underlying + bytes from the hexadecimal seed key. + + NOTE: Since the encryption mechanism has been switched, you need to run + this script to upgrade: + + https://gist.github.com/kaspth/bc37989c2f39a5642112f28b1d93f343 + + *Stephen Touset* + ## Rails 5.1.0.beta1 (February 23, 2017) ## * Add encrypted secrets in `config/secrets.yml.enc`. diff --git a/railties/lib/rails/commands/secrets/secrets_command.rb b/railties/lib/rails/commands/secrets/secrets_command.rb index 65db81ac73..b9ae5d8b3b 100644 --- a/railties/lib/rails/commands/secrets/secrets_command.rb +++ b/railties/lib/rails/commands/secrets/secrets_command.rb @@ -18,7 +18,7 @@ module Rails end def edit - if ENV["EDITOR"].empty? + if ENV["EDITOR"].to_s.empty? say "No $EDITOR to open decrypted secrets in. Assign one like this:" say "" say %(EDITOR="mate --wait" bin/rails secrets:edit) diff --git a/railties/lib/rails/secrets.rb b/railties/lib/rails/secrets.rb index a083914109..2a95712cd9 100644 --- a/railties/lib/rails/secrets.rb +++ b/railties/lib/rails/secrets.rb @@ -1,4 +1,5 @@ require "yaml" +require "active_support/message_encryptor" module Rails # Greatly inspired by Ara T. Howard's magnificent sekrets gem. 😘 @@ -12,6 +13,7 @@ module Rails end end + @cipher = "aes-128-gcm" @read_encrypted_secrets = false @root = File # Wonky, but ensures `join` uses the current directory. @@ -30,20 +32,19 @@ module Rails end def generate_key - cipher = new_cipher - SecureRandom.hex(cipher.key_len)[0, cipher.key_len] + SecureRandom.hex(OpenSSL::Cipher.new(@cipher).key_len) end def key ENV["RAILS_MASTER_KEY"] || read_key_file || handle_missing_key end - def encrypt(text) - cipher(:encrypt, text) + def encrypt(data) + encryptor.encrypt_and_sign(data) end def decrypt(data) - cipher(:decrypt, data) + encryptor.decrypt_and_verify(data) end def read @@ -97,14 +98,8 @@ module Rails end end - def new_cipher - OpenSSL::Cipher.new("aes-256-cbc") - end - - def cipher(mode, data) - cipher = new_cipher.public_send(mode) - cipher.key = key - cipher.update(data) << cipher.final + def encryptor + @encryptor ||= ActiveSupport::MessageEncryptor.new([ key ].pack("H*"), cipher: @cipher) end end end diff --git a/railties/test/secrets_test.rb b/railties/test/secrets_test.rb index 36e42cf1f9..953408f0b4 100644 --- a/railties/test/secrets_test.rb +++ b/railties/test/secrets_test.rb @@ -54,9 +54,9 @@ class Rails::SecretsTest < ActiveSupport::TestCase test "reading from key file" do run_secrets_generator do - File.binwrite("config/secrets.yml.key", "How do I know you feel it?") + File.binwrite("config/secrets.yml.key", "00112233445566778899aabbccddeeff") - assert_equal "How do I know you feel it?", Rails::Secrets.key + assert_equal "00112233445566778899aabbccddeeff", Rails::Secrets.key end end |