it-swarm-id.com

Apa cara yang benar untuk menerapkan token formulir anti-CSRF?

Saya sepenuhnya menyadari CSRF dan telah menerapkan beberapa formulir aman, tetapi saya belum pernah puas dengan hasilnya.

Saya telah membuat token sebagai md5 nama pengguna, info formulir dan garam dan menyimpannya dalam satu sesi. Ini memiliki masalah dengan penjelajahan dengan tab (dapat diperbaiki dengan menjaga array hash aktif) dan dengan pengaturan waktu. Saya ingin hash saya berfungsi hanya untuk mis. 10 menit, tetapi bagaimana saya menempatkan variabel terkait waktu dalam hash?

Adakah yang bisa mengarahkan saya ke sumber yang bagus yang menjelaskan cara membuat keamanan CSRF dengan benar?

34
naugtur

Cara terbaik untuk membangun perlindungan CSRF dengan benar:

Jangan.

Kerangka kerja yang paling umum memiliki perlindungan ini sudah dibangun di dalam (ASP.NET, Struts, Ruby Saya pikir), atau ada perpustakaan yang sudah ada yang telah diperiksa. (Misalnya CSRFGuard OWASP ).

Pilihan lain, tergantung pada konteks Anda, adalah untuk menegakkan kembali autentikasi pengguna, tetapi hanya untuk operasi spesifik dan sensitif.


Sesuai komentar Anda, jika Anda perlu menerapkan ini sendiri, solusi Anda tidak terlalu buruk, tapi saya akan menyederhanakannya.
Anda dapat membuat nonce crypto-random (cukup lama), menyimpannya dalam memori sesi, dan mengubahnya setiap X menit (Anda juga menyimpan waktu kedaluwarsa dalam sesi). Di setiap formulir, Anda menyertakan nonce di bidang formulir tersembunyi, dan membandingkan nilai itu ketika formulir diposting.
Jika token form cocok, Anda jelas. Jika tidak, Anda dapat menerima, mis. token sebelumnya juga, untuk menangani kasus Edge.

Meskipun saya harus mengatakan bahwa saya telah melihat terlalu banyak upaya gagal dalam mengimplementasikan ini sendiri, untuk benar-benar merekomendasikan jalur ini. Anda masih lebih baik menemukan paket minimal untuk melakukan ini untuk Anda.

25
AviD

Ada penjelasan yang bagus tentang OWASP: OWASP CSRF Prevention Cheat Sheet

Singkatnya mereka mengatakan bahwa ada dua cara:

  1. Tambahkan token acak ke setiap sesi pengguna. Hanya jika token ini ada dan benar perubahan akan diterapkan, jika tidak maka permintaan harus ditolak. Penting bahwa token hanya dikirim dengan permintaan POST, karena permintaan GET dapat membocorkan token ke tempat yang berbeda (riwayat browser, file log, dll.).

    Dimungkinkan juga untuk menghasilkan token per permintaan, tetapi ini mengarah pada masalah kegunaan. Misalnya tombol kembali tidak akan berfungsi dengan baik lagi. Tetapi tentu saja keamanan akan ditingkatkan.

    Pastikan juga (untuk meningkatkan keamanan lebih lagi) bahwa token hanya dikirim melalui TLS, jadi tidak akan ada orang di tengah masalah.

  2. Opsi lainnya adalah menggunakan semacam tantangan - respons (misalnya CAPTCHA atau token satu kali).

OWASP-Page juga mencantumkan beberapa langkah yang tidak berhasil. Ini adalah

  • Menggunakan cookie (rahasia)
  • Tidak menggunakan permintaan GET
  • Transaksi multi-langkah
  • Penulisan Ulang URL
27
Andreas Arnold

Selain jawaban @Andreas Arnold ada alternatif. Saya menerapkan Encrypted Token Pattern dari OWasp.

Selain mencegah serangan csrf, ia memiliki keuntungan tambahan menerapkan keamanan objek.

Hanya mereka yang berwenang untuk memodifikasi objek, yang dapat melakukannya. Orang lain tidak akan memiliki teks atau kunci sandi yang benar/valid. Saya biasanya mengenkripsi sessionId, timestamp, userId, dan/atau recordId.

timestamp mencegah replayAttacks. sessionid mengisolasi perubahan hanya untuk sesi ini userId mengisolasi perubahan hanya untuk pengguna ini. Jika Anda memasukkan recordId, maka dengan biaya pemrosesan ekstra Anda mendapatkan keamanan lebih.

3
Nasir