Rails Development-Mode secret_key_base RCE
- Product
- Ruby on Rails Rails (railties)
- CVE
- CVE-2019-5420
- Disclosed
- 2019-03-13
- CVSS
- 9.8
- Auth
- pre-auth
- CISA KEV
- no
- Affected
- 5.2.x < 5.2.2.1, 6.0.0.beta1 - 6.0.0.beta2 (development mode)
- Fixed
- 5.2.2.1, 6.0.0.beta3
Summary
In development mode Rails derived secret_key_base from the application's class name, so the key used to sign cookies and Active Storage URLs was guessable. Knowing it lets an attacker sign a Marshal-serialized object and get it deserialized, giving code execution on any dev-mode Rails app exposed to the network.
Root cause
Rails.application.secret_key_base fell back to Digest::MD5.hexdigest(self.class.name) in development/test. Signed values (e.g. Active Storage disk service keys under /rails/active_storage/disk/) are verified with this key and then deserialized with Marshal.load, so a forged value triggers a Ruby deserialization gadget chain.
Impact
Unauthenticated RCE against Rails apps running in development mode (often exposed staging/dev boxes).
Public PoC
1. Check the app is vulnerable to CVE-2019-5418 (Accept: ../../../../etc/passwd{{ file read)
2. Read credentials.yml.enc and master.key
3. Decrypt credentials.yml.enc to get secret_key_base
(dev mode fallback: Digest::MD5.hexdigest("<AppName>::Application"))
4. Craft a signed Marshal payload for
/rails/active_storage/disk/:encoded_key/*filename(.:format) => CVE-2019-5420
5. Send the request; the object is deserialized and code executesSource: mpgn / Rails-doubletap-RCE
Detection
Check for RAILS_ENV=development on internet-facing hosts and requests to /rails/active_storage/disk/ with long signed blobs. Version check railties < 5.2.2.1.
Mitigation
Upgrade to 5.2.2.1+ (dev secret is now random in tmp/development_secret.txt); never expose development mode.