secret_token.rb adalah file inisialisasi di Ruby on Rails (terletak di config/initializers/secret_token.rb) yang bertugas menyimpan kunci kriptografi rahasia untuk menandatangani (sign) dan mengenkripsi cookie sesi HTTP. Kunci ini memastikan bahwa data sesi yang disimpan di browser pengguna tidak dapat dimanipulasi atau dipalsukan oleh pihak ketiga.
Jika file ini bocor ke repositori publik (seperti GitHub), penyerang dapat memalsukan cookie sesi, memalsukan identitas pengguna (termasuk akun administrator), hingga mengeksekusi kode berbahaya secara jarak jauh (Remote Code Execution/RCE) melalui deserialisasi objek Ruby Marshal. Mulai Rails 4 dan versi modern (Rails 5 hingga Rails 8), implementasi secret_token telah ditinggalkan dan digantikan oleh secret_key_base serta sistem Encrypted Credentials.
Fungsi Utama dan Cara Kerja secret_token.rb
Saat aplikasi Rails menggunakan modul ActionDispatch::Session::CookieStore, status sesi pengguna disimpan langsung di sisi klien dalam bentuk cookie terenkripsi atau bertanda tangan digital. secret_token bertindak sebagai HMAC secret key untuk memvalidasi integritas data tersebut.
# Contoh isi config/initializers/secret_token.rb (Rails 3.x / Rails 4 legacy)
MyApp::Application.config.secret_token = '9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f'Jika nilai token ini diubah di server, seluruh sesi pengguna aktif akan otomatis menjadi tidak valid (invalidated), memaksa seluruh pengguna untuk melakukan login ulang karena tanda tangan verifikasi cookie tidak lagi cocok.
Evolusi Manajemen Rahasia Session di Ruby on Rails
Arsitektur keamanan Rails telah berkembang pesat untuk mencegah pengembang menyematkan kunci rahasia langsung dalam kode sumber (hardcoded secret). Tabel berikut merangkum evolusi penanganan token sesi dari masa ke masa:
| Versi Rails | Mekanisme Penyimpanan | Lokasi File Konfigurasi | Tingkat Keamanan Default |
|---|---|---|---|
| Rails 3.x | config.secret_token | config/initializers/secret_token.rb | Rentan jika di-commit ke Git (Plaintext) |
| Rails 4.0 - 4.1 | config.secret_key_base | config/initializers/secret_token.rb | Mendukung enkripsi cookie AES-256 |
| Rails 4.2 - 5.1 | secrets.yml | config/secrets.yml | Mulai memisahkan token dev/prod via ENV |
| Rails 5.2 - 7.x | Encrypted Credentials | config/credentials.yml.enc | Kredensial terenkripsi dengan master.key |
| Rails 8.x | Credentials / ENV Hybrid | config/credentials/*.yml.enc | Zero plain secrets di repositori kode |
Risiko Keamanan Fatal: Dari Bocornya Token ke Remote Code Execution (RCE)
Pada Rails versi lama, data cookie diserialisasi menggunakan modul bawaan Ruby, yaitu Marshal. Jika seorang peretas mengetahui nilai secret_token atau secret_key_base aplikasi, langkah eksploitasi berlangsung sangat cepat:
- Cookie Forgery: Peretas membuat payload sesi palsu di mesin lokal, misalnya mengubah parameter
user_id: 1untuk langsung mengambil alih akun Superadmin tanpa kata sandi. - Deserialization Attack: Peretas menyusun gadget chain objek Ruby (misalnya memanfaatkan class
ERBatau objek universal Ruby lainnya) ke dalam payload sesi yang ditandatangani menggunakan token curian. - Arbitrary Command Execution: Saat request dikirim ke server, Rails mendeteksi tanda tangan HMAC cocok dan langsung mendeserialisasi data dengan
Marshal.load, memicu eksekusi perintah shell langsung di server target.
Cara Migrasi Aman dari secret_token.rb ke Rails Modern
Bagi proyek yang masih memiliki residu file config/initializers/secret_token.rb atau sedang melakukan modernisasi aplikasi, ikuti langkah-langkah standardisasi industri berikut:
1. Pindahkan Kunci ke Environment Variable (Jika Menggunakan Rails 4/5)
Hapus nilai string plaintext dari repository dan baca langsung dari variabel lingkungan server produksi:
# config/initializers/secret_token.rb
Rails.application.config.secret_key_base = ENV['SECRET_KEY_BASE'] || begin
if Rails.env.production?
raise 'SECRET_KEY_BASE environment variable is missing in production!'
else
'development_secret_key_base_fallback_for_local_testing_only_1234567890'
end
end2. Migrasi ke Rails Encrypted Credentials (Rails 5.2 ke Atas)
Hapus file config/initializers/secret_token.rb secara permanen, lalu manfaatkan sistem enkripsi bawaan Rails:
# Hapus initializer usang
git rm config/initializers/secret_token.rb
-- Generate kunci credentials baru jika belum ada
EDITOR="nano" bin/rails credentials:editDi dalam editor yang terbuka, pastikan secret_key_base terkonfigurasi:
# config/credentials.yml.enc
secret_key_base: c894d0e91f1a547b744031a0e0e0ab72d7f8d6f021ad5e8c1b3f94e9f7823ab498c812d38f...Menghasilkan Token Baru dan Troubleshooting Error
Untuk men-generate string token acak dengan entropi tinggi (64-byte hex string), jalankan perintah Rake/Rails berikut di terminal:
bundle exec rake secret
# Atau pada Rails versi baru:
bin/rails secretSolusi Error: "ArgumentError: A secret is required to generate an integrity hash for cookie session data"
Pesan kesalahan ini muncul saat aplikasi Rails melakukan booting di environment production namun tidak menemukan nilai secret_key_base atau secret_token. Langkah penanganannya:
- Jalankan
bin/rails secretdi terminal lokal untuk mendapatkan string 128 karakter acak. - Tambahkan string tersebut ke environment server Anda:
export SECRET_KEY_BASE="string_dari_langkah_1". - Jika menggunakan Heroku:
heroku config:set SECRET_KEY_BASE="$(bundle exec rake secret)". - Jika menggunakan Docker, masukkan ke dalam file
.env.productionatau secret manager container runner.
Tindakan Tanggap Darurat Jika secret_token Terlanjur Masuk Git
Jika file secret_token.rb berisi token asli sempat ter-push ke GitHub atau repositori publik, token tersebut wajib dianggap telah terkompromi. Langkah pembersihan yang harus dilakukan:
- Rotasi Token Seketika: Segera generate token baru dan terapkan di server produksi. Seluruh user akan log out otomatis, namun akses penyusup menggunakan token lama langsung tertutup.
- Bersihkan Riwayat Git: Gunakan tool seperti
git-filter-repoatau BFG Repo-Cleaner untuk menghapus commit historis yang memuat token tersebut sebelum repositori diakses publik kembali. Menghapus file di commit terbaru saja tidak cukup karena riwayat lama masih dapat dibaca penyerang. - Audit Log Server: Periksa log akses HTTP pada jam-jam token terekspos untuk mendeteksi anomali request dengan cookie berukuran besar yang mencurigakan.