Saya mengalami beberapa masalah tentang Token Keaslian di Rails, seperti yang saya miliki berkali-kali sekarang.
Tapi saya benar-benar tidak ingin menyelesaikan masalah ini dan teruskan. Saya benar-benar ingin memahami token Keaslian. Nah, pertanyaan saya adalah, apakah Anda memiliki sumber informasi lengkap tentang hal ini atau akankah Anda menghabiskan waktu untuk menjelaskan secara terperinci di sini?
ruby-on-rails
ruby
authenticity-token
Ricardo Acras
sumber
sumber
Jawaban:
Apa yang terjadi
Saat pengguna melihat formulir untuk membuat, memperbarui, atau menghancurkan sumber daya, aplikasi Rails membuat acak
authenticity_token
, menyimpan token ini di sesi, dan menempatkannya di bidang tersembunyi di formulir. Ketika pengguna mengirimkan formulir, Rails mencariauthenticity_token
, membandingkannya dengan yang disimpan dalam sesi, dan jika mereka cocok dengan permintaan diizinkan untuk melanjutkan.Kenapa itu terjadi?
Karena token keaslian disimpan dalam sesi, klien tidak dapat mengetahui nilainya. Ini mencegah orang mengirimkan formulir ke aplikasi Rails tanpa melihat formulir di dalam aplikasi itu sendiri. Bayangkan Anda menggunakan layanan A, Anda masuk ke layanan dan semuanya baik-baik saja. Sekarang bayangkan Anda pergi menggunakan layanan B, dan Anda melihat gambar yang Anda suka, dan menekan pada gambar untuk melihat ukuran yang lebih besar. Sekarang, jika ada kode jahat di layanan B, mungkin mengirim permintaan ke layanan A (yang Anda masuki), dan meminta untuk menghapus akun Anda, dengan mengirimkan permintaan ke
http://serviceA.com/close_account
. Inilah yang dikenal sebagai CSRF (Pemalsuan Permintaan Situs Lintas) .Jika layanan A menggunakan token keaslian, vektor serangan ini tidak lagi berlaku, karena permintaan dari layanan B tidak akan berisi token keaslian yang benar, dan tidak akan diizinkan untuk melanjutkan.
API API menjelaskan detail tentang tag meta:
Catatan
Perlu diingat, Rails hanya memverifikasi bukan metode idempoten (POST, PUT / PATCH dan DELETE). Permintaan GET tidak diperiksa untuk token keaslian. Mengapa? karena spesifikasi HTTP menyatakan bahwa permintaan GET adalah idempoten dan tidak boleh membuat, mengubah, atau menghancurkan sumber daya di server, dan permintaan tersebut harus idempoten (jika Anda menjalankan perintah yang sama beberapa kali, Anda harus mendapatkan hasil yang sama setiap kali).
Implementasi sebenarnya juga sedikit lebih rumit seperti yang didefinisikan di awal, memastikan keamanan yang lebih baik. Rails tidak mengeluarkan token tersimpan yang sama dengan setiap bentuk. Tidak juga menghasilkan dan menyimpan token yang berbeda setiap saat. Ini menghasilkan dan menyimpan hash kriptografi dalam sesi dan mengeluarkan token kriptografi baru, yang dapat dicocokkan dengan yang disimpan, setiap kali halaman diberikan. Lihat request_forgery_protection.rb .
Pelajaran
Gunakan
authenticity_token
untuk melindungi metode tidak idempoten Anda (POST, PUT / PATCH, dan DELETE). Pastikan juga untuk tidak mengizinkan permintaan GET yang berpotensi memodifikasi sumber daya di server.EDIT: Periksa komentar oleh @erturne tentang permintaan GET menjadi idempoten. Dia menjelaskannya dengan cara yang lebih baik daripada yang saya lakukan di sini.
sumber
Token keaslian dirancang agar Anda tahu formulir Anda dikirimkan dari situs web Anda. Ini dihasilkan dari mesin yang menjalankannya dengan pengenal unik yang hanya diketahui oleh mesin Anda, sehingga membantu mencegah serangan pemalsuan permintaan lintas situs.
Jika Anda hanya mengalami kesulitan dengan rel yang menolak akses skrip AJAX Anda, Anda dapat menggunakannya
untuk menghasilkan token yang benar ketika Anda membuat formulir Anda.
Anda dapat membaca lebih lanjut tentang itu di dokumentasi .
sumber
Apa itu CSRF?
Token Keaslian adalah tindakan balasan untuk Pemalsuan Permintaan Lintas Situs (CSRF). Apa itu CSRF, Anda bertanya?
Ini adalah cara penyerang berpotensi membajak sesi tanpa mengetahui token sesi.
Skenario :
Solusi CSRF :
sumber
Contoh serangan minimal yang akan dicegah: CSRF
Di situs web saya,
evil.com
saya meyakinkan Anda untuk mengirimkan formulir berikut:Jika Anda masuk ke bank melalui cookie sesi, maka cookie akan dikirim dan transfer akan dilakukan tanpa Anda menyadarinya.
Itulah saat token CSRF ikut berperan:
Jadi bentuk pada browser yang otentik akan terlihat seperti:
Dengan demikian, serangan saya akan gagal, karena tidak mengirim
authenticity_token
parameter, dan tidak mungkin saya bisa menebaknya karena ini adalah angka acak yang sangat besar.Teknik pencegahan ini disebut Pola Sinkronisasi Token .
Kebijakan Asal yang Sama
Tetapi bagaimana jika penyerang membuat dua permintaan dengan JavaScript, satu untuk membaca token, dan yang kedua untuk melakukan transfer?
Pola token sinkronisasi saja tidak cukup untuk mencegahnya!
Di sinilah Kebijakan Same Origin datang untuk menyelamatkan, seperti yang telah saya jelaskan di: /security/8264/why-is-the-same-origin-policy-so-important/72569# 72569
Bagaimana Rails mengirim token
Tercakup di: Rails: Bagaimana cara csrf_meta_tag Bekerja?
Pada dasarnya:
Pembantu HTML suka
form_tag
menambahkan bidang tersembunyi ke formulir untuk Anda jika itu bukan formulir GETAJAX ditangani secara otomatis oleh jquery-ujs , yang membaca token dari
meta
elemen yang ditambahkan ke header Anda dengancsrf_meta_tags
(hadir dalam templat default), dan menambahkannya ke setiap permintaan yang dibuat.uJS juga mencoba memperbarui token dalam bentuk dalam fragmen cache yang ketinggalan zaman.
Pendekatan pencegahan lainnya
X-Requested-With
:Origin
header: /security/91165/why-is-the-synchronizer-token-pattern-preferred-over-the-origin-header-check-tosumber
Token keaslian digunakan untuk mencegah serangan Pemalsuan Permintaan Situs-Lintas (CSRF). Untuk memahami token keaslian, Anda harus terlebih dahulu memahami serangan CSRF.
CSRF
Misalkan Anda adalah penulis
bank.com
. Anda memiliki formulir di situs Anda yang digunakan untuk mentransfer uang ke akun lain dengan permintaan GET:Seorang hacker hanya bisa mengirim permintaan HTTP ke server dengan mengatakan
GET /transfer?amount=$1000000&account-to=999999
, bukan?Salah. Serangan peretas tidak akan berhasil. Server pada dasarnya akan berpikir?
Bagaimana server mengetahui hal ini? Karena tidak ada
session_id
cookie yang mengotentikasi pemohon.Saat Anda masuk dengan nama pengguna dan kata sandi, server menetapkan
session_id
cookie di browser Anda. Dengan begitu, Anda tidak perlu mengautentikasi setiap permintaan dengan nama pengguna dan kata sandi Anda. Saat browser Anda mengirimkansession_id
cookie, server tahu:Seorang hacker mungkin berpikir:
Browser pengguna memiliki banyak cookie yang ditetapkan untuk
bank.com
domain. Setiap kali pengguna mengajukan permintaan kebank.com
domain, semua cookie dikirimkan. Termasuksession_id
cookie.Jadi jika seorang hacker dapat membuat Anda membuat permintaan GET yang mentransfer uang ke akunnya, ia akan berhasil. Bagaimana dia bisa menipu Anda untuk melakukannya? Dengan Pemalsuan Permintaan Lintas Situs.
Sebenarnya cukup sederhana. Peretas hanya bisa membuat Anda mengunjungi situs webnya. Di situs webnya, ia dapat memiliki tag gambar berikut:
Ketika browser pengguna menemukan tag gambar itu, itu akan membuat permintaan GET ke url itu. Dan karena permintaan berasal dari perambannya, ia akan mengirim semua cookie yang terkait dengannya
bank.com
. Jika pengguna baru saja masuk kebank.com
...session_id
cookie akan ditetapkan, dan server akan berpikir bahwa pengguna bermaksud untuk mentransfer $ 1.000.000 ke akun 999999!Itu tidak cukup. Bagaimana jika seseorang memposting gambar itu ke Facebook dan itu muncul di dinding Anda? Bagaimana jika itu disuntikkan ke situs yang Anda kunjungi dengan serangan XSS?
Tidak benar. Formulir yang mengirimkan permintaan POST dapat dibuat secara dinamis. Berikut adalah contoh dari Panduan Rails tentang Keamanan :
Token Keaslian
Ketika Anda
ApplicationController
memiliki ini:Ini:
Dikompilasi menjadi ini:
Secara khusus, berikut ini dihasilkan:
Untuk melindungi dari serangan CSRF, jika Rails tidak melihat token keaslian yang dikirimkan bersama dengan permintaan, itu tidak akan menganggap permintaan itu aman.
Bagaimana penyerang bisa tahu apa token ini? Nilai berbeda dihasilkan secara acak setiap kali formulir dihasilkan:
Serangan Lintas Situs Skrip (XSS) - begitulah. Tapi itu kerentanan yang berbeda untuk hari yang berbeda.
sumber
Ini
Authenticity Token
adalah metode rel untuk mencegah serangan pemalsuan permintaan lintas situs (CSRF atau XSRF) .Sederhananya, itu memastikan bahwa PUT / POST / HAPUS (metode yang dapat mengubah konten) permintaan ke aplikasi web Anda dibuat dari browser klien dan bukan dari pihak ketiga (penyerang) yang memiliki akses ke cookie yang dibuat di sisi klien.
sumber
karena
Authenticity Token
sangat penting, dan di Rails 3.0+ Anda dapat menggunakanuntuk membuat
dimana saja
sumber
XSS
pada halaman login, bukan untuk tujuan jahat, tetapi untuk membuat sesi baru dengan nama pengguna yang sudah diisi sebelumnya. Sekarang saya tahu saya bisa menggunakannyavalue="token_value"
.Waspadai mekanisme Token Keaslian dapat menyebabkan kondisi ras jika Anda memiliki beberapa permintaan bersamaan dari klien yang sama. Dalam situasi ini server Anda dapat menghasilkan beberapa token keaslian ketika seharusnya hanya ada satu, dan klien yang menerima token sebelumnya dalam bentuk akan gagal pada permintaan berikutnya karena token cookie sesi telah ditimpa. Ada tulisan tentang masalah ini dan solusi yang tidak sepenuhnya sepele di sini: http://www.paulbutcher.com/2007/05/race-conditions-in-rails-sessions-and-how-to-fix-them/
sumber
Metode Dimana
authenticity_token
diperlukanMengapa Itu Diperlukan
sumber
Apa itu otentikasi_token?
Ini adalah string acak yang digunakan oleh aplikasi rails untuk memastikan bahwa pengguna meminta atau melakukan tindakan dari halaman aplikasi, bukan dari aplikasi atau situs lain.
Mengapa otentikasi_token diperlukan?
Untuk melindungi aplikasi atau situs Anda dari pemalsuan permintaan lintas situs.
Bagaimana cara menambahkan authentication_token ke formulir?
Jika Anda membuat formulir menggunakan tag form_for, otentikasi_token ditambahkan secara otomatis yang dapat Anda gunakan
<%= csrf_meta_tag %>
.sumber