[RUBY] Achten Sie bei der Verwendung von MessageEncryptor mit Rails 5.2 / 6.0 auf den Zeitpunkt der Initialisierung

Ab Rails 5.2 wurde die Standardverschlüsselungsmethode für "ActiveSupport :: MessageEncryptor" von "aes-256-cbc" in "aes-256-gcm" geändert. Abhängig vom Zeitpunkt der Initialisierung kann jedoch eine unbeabsichtigte Verschlüsselungsmethode verwendet werden, sodass wir sie einführen werden.

Rails 5.2

Überprüfen Sie mit den folgenden Versionen:

Standard

Überprüfen Sie zunächst die Standardverschlüsselungsmethode mit "Rails Console".

irb> encryptor = ActiveSupport::MessageEncryptor.new 'key'
=> #<ActiveSupport::MessageEncryptor:0x0000561c2eae8940 @secret="key", @sign_secret=nil, @cipher="aes-256-gcm", @aead_mode=true, @verifier=ActiveSupport::MessageEncryptor::NullVerifier, @serializer=Marshal, @options={}, @rotations=[]>
irb> encryptor.instance_variable_get '@cipher'
=> "aes-256-gcm"

Es stellt sich heraus, dass es "aes-256-gcm" ist.

Illustration

In einer tatsächlichen Anwendung kann es verwendet werden, indem es in einem Modell vorhanden ist.

app/models/some_model.rb


class SomeModel < ApplicationRecord
  class << self
    attr_reader :encryptor

    def set_key(key)
      @encryptor = ActiveSupport::MessageEncryptor.new key
    end
  end

  set_key 'x' * 32
end

Überprüfen Sie dies auf die gleiche Weise.

irb> SomeModel.encryptor.instance_variable_get '@cipher'
=> "aes-256-gcm"

Sieht gut aus.

Problembeispiel

Wenn jedoch der Initialisierungszeitpunkt von "MessageEncryptor" zu früh ist, unterscheidet sich die Verschlüsselungsmethode. Wenn beispielsweise die Konstante "SomeModel" im Rückruf "after_initialize" referenziert wird, wird sie zu diesem Zeitpunkt automatisch geladen und ein "MessageEncryptor" generiert.

config/application.rb


class Application < Rails::Application
  config.load_defaults 5.2
  config.after_initialize do
    SomeModel
  end
end
irb> SomeModel.encryptor.instance_variable_get '@cipher'
=> "aes-256-cbc"

Es ist zu "aes-256-cbc" anstelle von "aes-256-gcm" geworden.

Ursache

Das Problem ist der Zeitpunkt, zu dem die Einstellungen von "Rails.application.config.active_support.use_authenticated_message_encryption" wiedergegeben werden. Diese Einstellung dient der Kompatibilität mit früheren Versionen. Sie können die Standardverschlüsselungsmethode auf "aes-256-cbc" zurücksetzen, indem Sie sie auf "false" setzen. Dieser Einstellungswert ist der Standardwert "true" für Rails 5.2, aber es scheint, dass dieser Einstellungswert zum Zeitpunkt der Ausführung von "config.after_initialize" noch nicht berücksichtigt wurde. Wenn es zu diesem Zeitpunkt initialisiert wird, ist es daher "aes-256-cbc", was die Standardeinstellung von "MessageEncryptor" selbst ist.

Der entsprechende Code ist hier.

https://github.com/rails/rails/blob/v5.2.4.3/activesupport/lib/active_support/message_encryptor.rb#L88

Lösungsbeispiel

Da das Problem darin besteht, dass die Initialisierung zu früh ist, kann sie bis zum tatsächlichen Verwendungszeitpunkt verzögert werden.

app/models/some_model2.rb


class SomeModel2 < ApplicationRecord
  class << self
    def set_key(key)
      @key = key
    end

    def encryptor
      @encryptor ||= ActiveSupport::MessageEncryptor.new @key
    end
  end

  set_key 'x' * 32
end

config/application.rb


config.after_initialize do
  SomeModel2
end

Jetzt können Sie in den meisten Fällen "aes-256-gcm" verwenden.

irb> SomeModel2.encryptor.instance_variable_get '@cipher'
=> "aes-256-gcm"

Wenn jedoch das Timing selbst, wenn Sie "MessageEncryptor" verwenden möchten, vor der Einstellung von "use_authenticated_message_encryption" liegt, wird das Problem nicht gelöst. In diesem Fall ist es besser, die Option "cipher:" in "MessageEncryptor.new" anzugeben.

Rails 6

Ich habe mit der folgenden Version erneut nachgeforscht, aber es scheint, dass die Situation dieselbe ist.

Ein wenig anders als in 5.2 ist, dass der Standard-Autoloader Zeitwerk ist und es veraltet ist, jedes Modell mit config / initializers / *. Rb automatisch zu laden. Wenn Sie versehentlich mit config / initializers / *. Rb auf das Modell verweisen, kann dies mit einer Warnmeldung erkannt werden. Wie im Beispiel in diesem Artikel scheint es jedoch in config.after_initialize keine Warnung zu geben.

Rails lädt jede Datei nach Bedarf, aber das Timing kann manchmal verwirrend sein. Beachten Sie, dass der Ladezeitpunkt Probleme verursachen kann.

Recommended Posts

Achten Sie bei der Verwendung von MessageEncryptor mit Rails 5.2 / 6.0 auf den Zeitpunkt der Initialisierung
[Schienen] Beachten Sie bei der Verwendung von Ajax die "CSRF-Maßnahmen".
Seien Sie vorsichtig, wenn Sie mehrere Artikel verwenden
Initialisierungszeitpunkt der Mitgliedsvariablen mit endgültiger Angabe
Seien Sie vorsichtig mit Anfragen und Antworten, wenn Sie das Serverless Framework mit Java verwenden
[Java10] Achten Sie darauf, var und generics nicht zusammen zu verwenden
Festlegen von Umgebungsvariablen bei Verwendung von Payjp mit Rails
Japanisieren Sie mit i18n mit Rails
Zusammenfassung der ersten Arbeiten beim Erstellen einer App mit Rails
Fehler bei der Verwendung von Schienen Capybara
[Rails] Bei der Beschreibung der Validierung ist Vorsicht geboten
Detaillierte Tipps zur Verwendung von Rails
[Rails] Japanische Lokalisierung der Fehlermeldung bei Verwendung des Formularobjekts
Beachten Sie beim Upgrade von Tomcat auf einem Web-System, das Oracle verwendet
[Rails] Implementierung der Couponfunktion (mit automatischer Löschfunktion mittels Stapelverarbeitung)
Einstellungen, die beim Betrieb einer Produktionsumgebung mit Rails vorgenommen werden sollten
[Rails] "Pry-Rails", die beim Speichern mit der create-Methode verwendet werden können
Eine Sammlung von Methoden, die häufig beim Bearbeiten der Zeit mit TimeWithZone of Rails verwendet werden
Visualisieren Sie die Verarbeitungszeit des Rails-Servers mithilfe des Server-Timings
[Rails] Beiträge können nicht gelöscht werden, wenn sie kommentiert werden! ??
Hinweise zur Verwendung von FCM mit Ruby on Rails
Verwendung eines versteckten Typs beim PUT mit Thymeleaf
Verwenden Sie SSIServlet mit dem in SpringBoot 2.2.4 integrierten Tomcat
Achten Sie auf die Sommerzeit, wenn Sie den Geburtstag eines Benutzers neu registrieren / referenzieren
Problem der langsamen Verarbeitung bei Verwendung von Active Storage mit Cloud-Speicher (GCS, S3 usw.)