Saya mencoba memahami seluruh masalah dengan CSRF dan cara yang tepat untuk mencegahnya. (Sumber yang telah saya baca, pahami, dan setujui dengan: Lembar Cegah Pencegahan CSRF OWASP , Pertanyaan tentang CSRF .)
Seperti yang saya pahami, kerentanan sekitar CSRF diperkenalkan oleh asumsi bahwa (dari sudut pandang server web) cookie sesi yang valid dalam permintaan HTTP masuk mencerminkan keinginan pengguna yang diautentikasi. Tetapi semua cookie untuk domain asal secara ajaib dilampirkan ke permintaan oleh browser, jadi benar-benar semua server dapat menyimpulkan dari kehadiran cookie sesi yang valid dalam permintaan adalah bahwa permintaan tersebut berasal dari browser yang memiliki sesi terotentikasi; lebih lanjut tidak dapat menganggap apa pun tentang kodeberjalan di browser itu, atau apakah itu benar-benar mencerminkan keinginan pengguna. Cara untuk mencegah ini adalah dengan memasukkan informasi otentikasi tambahan ("token CSRF") dalam permintaan, yang dilakukan dengan beberapa cara selain penanganan cookie otomatis browser. Secara longgar, cookie sesi mengotentikasi pengguna / browser dan token CSRF mengotentikasi kode yang berjalan di browser.
Singkatnya, jika Anda menggunakan cookie sesi untuk mengautentikasi pengguna aplikasi web Anda, Anda juga harus menambahkan token CSRF untuk setiap respons, dan memerlukan token CSRF yang cocok di setiap permintaan (yang bermutasi). Token CSRF kemudian melakukan bolak-balik dari server ke browser kembali ke server, membuktikan ke server bahwa halaman yang membuat permintaan disetujui oleh (dihasilkan oleh, bahkan) server itu.
Ke pertanyaan saya, yaitu tentang metode transportasi spesifik yang digunakan untuk token CSRF pada perjalanan pulang pergi itu.
Tampaknya umum (misalnya dalam AngularJS , Django , Rails ) untuk mengirim token CSRF dari server ke klien sebagai cookie (yaitu dalam header Set-Cookie), dan kemudian memiliki Javascript di klien mengikisnya keluar dari cookie dan melampirkannya sebagai header XSRF-TOKEN yang terpisah untuk mengirim kembali ke server.
(Metode alternatif adalah metode yang direkomendasikan oleh misalnya Express , di mana token CSRF yang dihasilkan oleh server dimasukkan dalam badan respons melalui ekspansi templat sisi-server, dilampirkan langsung ke kode / markup yang akan memasoknya kembali ke server, misalnya sebagai input formulir tersembunyi. Contoh itu adalah web yang lebih 1.0-ish cara melakukan sesuatu, tetapi akan menggeneralisasi baik untuk klien yang lebih berat JS.)
Mengapa Set-Cookie sangat umum digunakan sebagai transportasi hilir untuk token CSRF / mengapa ini ide yang bagus? Saya membayangkan penulis dari semua kerangka kerja ini mempertimbangkan pilihan mereka dengan hati-hati dan tidak salah. Tetapi pada pandangan pertama, menggunakan cookie untuk mengatasi apa yang pada dasarnya pembatasan desain pada cookie tampaknya bodoh. Bahkan, jika Anda menggunakan cookie sebagai transportasi pulang pergi (Set-Cookie: header hilir untuk server untuk memberitahu browser token CSRF, dan Cookie: header hulu untuk browser untuk mengembalikannya ke server) Anda akan memperkenalkan kembali kerentanan Anda sedang mencoba untuk memperbaikinya.
Saya menyadari bahwa kerangka kerja di atas tidak menggunakan cookie untuk seluruh perjalanan pulang pergi untuk token CSRF; mereka menggunakan Set-Cookie downstream, lalu sesuatu yang lain (misalnya header X-CSRF-Token) upstream, dan ini tidak menutup kerentanan. Tetapi bahkan menggunakan Set-Cookie sebagai transportasi hilir berpotensi menyesatkan dan berbahaya; browser sekarang akan melampirkan token CSRF untuk setiap permintaan termasuk permintaan XSRF berbahaya asli; paling-paling itu membuat permintaan lebih besar dari yang seharusnya dan paling buruk beberapa kode server yang bermaksud baik tetapi salah arah mungkin benar-benar mencoba menggunakannya, yang akan sangat buruk. Dan lebih jauh lagi, karena penerima token CSRF yang sebenarnya dimaksudkan adalah Javascript sisi klien, itu artinya cookie ini tidak dapat dilindungi hanya dengan http.