Sepertinya keberatan Anda untuk membiarkan sesi tetap terbuka selama browser terbuka adalah masalah serangan otomatis. Sayangnya, menyegarkan token pada setiap pemuatan halaman hanya menghalangi sebagian besar penyerang amatir.
Pertama, saya berasumsi kita sedang berbicara tentang serangan yang secara khusus ditargetkan ke situs Anda. (Jika kita berbicara tentang bot yang hanya berkeliaran dan mengirimkan berbagai formulir, ini tidak hanya akan menghentikan mereka, tetapi ada cara yang jauh lebih baik dan lebih mudah untuk melakukannya.) Jika itu masalahnya, dan saya menargetkan situs, inilah yang akan dilakukan bot saya:
- Muat halaman formulir.
- Baca token di halaman formulir.
- Kirim permintaan otomatis dengan token itu.
- Lanjutkan ke langkah 1.
(Atau, jika saya cukup menyelidiki sistem Anda, saya akan menyadari bahwa jika saya menyertakan tajuk "ini AJAX" pada setiap permintaan, saya dapat menyimpan satu token selamanya. Atau saya akan menyadari bahwa token tersebut adalah ID sesi saya, dan kirim PHPSESSID
saya sendiri kue.)
Metode mengubah token pada setiap pemuatan halaman ini sama sekali tidak akan menghentikan seseorang yang sebenarnya ingin untuk menyerang Anda semua yang buruk. Oleh karena itu, karena token tidak berpengaruh pada otomatisasi, fokuslah pada efeknya pada CSRF.
Dari perspektif memblokir CSRF, membuat satu token dan memeliharanya hingga pengguna menutup browser tampaknya mencapai semua tujuan. Serangan CSRF sederhana dikalahkan, dan pengguna dapat membuka banyak tab.
TL;DR:Menyegarkan token sekali pada setiap permintaan tidak meningkatkan keamanan. Gunakan kegunaan dan lakukan satu token per sesi.
Namun! Jika Anda sangat khawatir tentang pengiriman formulir duplikat, tidak disengaja atau tidak, masalah ini masih dapat diselesaikan dengan mudah. Jawabannya sederhana:gunakan dua token untuk dua pekerjaan berbeda.
Token pertama akan tetap sama sampai sesi browser berakhir. Token ini ada untuk mencegah serangan CSRF. Setiap pengiriman dari pengguna ini dengan token ini akan diterima.
Token kedua akan dibuat secara unik untuk setiap formulir yang dimuat, dan akan disimpan dalam daftar di data sesi pengguna dari token formulir terbuka. Token ini unik dan tidak berlaku setelah digunakan. Kiriman dari pengguna ini dengan token ini akan diterima sekali dan hanya sekali.
Dengan cara ini, jika saya membuka tab ke Formulir A dan tab ke Formulir B, masing-masing memiliki token anti-CSRF pribadi saya (CSRF diurus), dan token formulir satu kali saya (pengiriman ulang formulir diurus). Kedua masalah diselesaikan tanpa efek buruk pada pengalaman pengguna.
Tentu saja, Anda mungkin memutuskan bahwa itu terlalu banyak untuk diterapkan untuk fitur yang begitu sederhana. Saya pikir itu, bagaimanapun juga. Apapun, solusi yang solid ada jika Anda menginginkannya.