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?
Hah? Siapa pria ini yang mencoba melakukan transfer. Bukan pemilik akun, itu sudah pasti.
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 mengirimkan session_id
cookie, server tahu:
Oh, itu John Doe. Dia berhasil masuk 2,5 menit yang lalu. Dia baik untuk pergi.
Seorang hacker mungkin berpikir:
Hmm. Permintaan HTTP normal tidak akan berfungsi, tetapi jika saya bisa mendapatkan session_id
cookie itu, saya akan menjadi emas.
Browser pengguna memiliki banyak cookie yang ditetapkan untuk bank.com
domain. Setiap kali pengguna mengajukan permintaan ke bank.com
domain, semua cookie dikirimkan. Termasuk session_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:
<img src="http://bank.com/transfer?amount=$1000000&account-to=999999">
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 ke bank.com
... session_id
cookie akan ditetapkan, dan server akan berpikir bahwa pengguna bermaksud untuk mentransfer $ 1.000.000 ke akun 999999!
Yah, jangan mengunjungi situs berbahaya dan Anda akan baik-baik saja.
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?
Itu tidak terlalu buruk. Hanya permintaan GET yang rentan.
Tidak benar. Formulir yang mengirimkan permintaan POST dapat dibuat secara dinamis. Berikut adalah contoh dari Panduan Rails tentang Keamanan :
<a href="http://www.harmless.com/" onclick="
var f = document.createElement('form');
f.style.display = 'none';
this.parentNode.appendChild(f);
f.method = 'POST';
f.action = 'http://www.example.com/account/destroy';
f.submit();
return false;">To the harmless survey</a>
Token Keaslian
Ketika Anda ApplicationController
memiliki ini:
protect_from_forgery with: :exception
Ini:
<%= form_tag do %>
Form contents
<% end %>
Dikompilasi menjadi ini:
<form accept-charset="UTF-8" action="/" method="post">
<input name="utf8" type="hidden" value="✓" />
<input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />
Form contents
</form>
Secara khusus, berikut ini dihasilkan:
<input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />
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.