Saya telah menerapkan mitigasi serangan CSRF di aplikasi saya mengikuti informasi yang saya baca di beberapa posting blog di internet. Khususnya posting ini telah menjadi pendorong implementasi saya
- Praktik Terbaik untuk ASP.NET MVC dari Tim Konten Pengembang ASP.NET dan Alat Web
- Anatomi Permintaan Lintas Situs Memalsukan Serangan dari blog Phil Haack
- AntiForgeryToken dalam ASP.NET MVC Framework - Html.AntiForgeryToken dan ValidasikanAntiForgeryToken Atribut dari blog David Hayden
Pada dasarnya artikel dan rekomendasi tersebut mengatakan bahwa untuk mencegah serangan CSRF, siapa pun harus menerapkan kode berikut:
1) Tambahkan [ValidateAntiForgeryToken]
pada setiap tindakan yang menerima kata kerja POST Http
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SomeAction( SomeModel model ) {
}
2) Tambahkan <%= Html.AntiForgeryToken() %>
helper form dalam yang mengirimkan data ke server
<div style="text-align:right; padding: 8px;">
<%= Html.AntiForgeryToken() %>
<input type="submit" id="btnSave" value="Save" />
</div>
Ngomong-ngomong di beberapa bagian aplikasi saya, saya melakukan POS Ajax dengan jQuery ke server tanpa memiliki bentuk apa pun. Ini terjadi misalnya ketika saya membiarkan pengguna mengklik gambar untuk melakukan tindakan tertentu.
Misalkan saya punya meja dengan daftar kegiatan. Saya memiliki gambar di kolom tabel yang mengatakan "Tandai aktivitas selesai" dan ketika pengguna mengklik aktivitas tersebut saya melakukan POST Ajax seperti dalam contoh berikut:
$("a.markAsDone").click(function (event) {
event.preventDefault();
$.ajax({
type: "post",
dataType: "html",
url: $(this).attr("rel"),
data: {},
success: function (response) {
// ....
}
});
});
Bagaimana saya bisa menggunakan <%= Html.AntiForgeryToken() %>
ini dalam kasus ini? Haruskah saya menyertakan panggilan pembantu di dalam parameter data panggilan Ajax?
Maaf untuk posting lama dan terima kasih banyak telah membantu
EDIT :
Sesuai jawaban jayrdub saya telah menggunakan cara berikut
$("a.markAsDone").click(function (event) {
event.preventDefault();
$.ajax({
type: "post",
dataType: "html",
url: $(this).attr("rel"),
data: {
AddAntiForgeryToken({}),
id: parseInt($(this).attr("title"))
},
success: function (response) {
// ....
}
});
});
Jawaban:
Saya menggunakan fungsi js sederhana seperti ini
Karena setiap formulir pada halaman akan memiliki nilai token yang sama, cukup masukkan sesuatu seperti ini di halaman master teratas Anda
Kemudian dalam panggilan ajax Anda lakukan (diedit untuk mencocokkan contoh kedua Anda)
sumber
AddAntiForgeryToken
, seperti:data: AddAntiForgeryToken({ id: parseInt($(this).attr("title")) }),
ajaxSend
atau digantiajax
untuk selalu menambahdata
token anti-pemalsuan? Mungkin menambahkan beberapa cek untuk memastikan bahwaurl
diperuntukkan bagi server Anda.Saya suka solusi yang disediakan oleh 360Airwalk, tetapi mungkin sedikit ditingkatkan.
Masalah pertama adalah bahwa jika Anda membuat
$.post()
dengan data kosong, jQuery tidak menambahkanContent-Type
header, dan dalam hal ini ASP.NET MVC gagal menerima dan memeriksa token. Jadi Anda harus memastikan tajuknya selalu ada.Peningkatan lainnya adalah dukungan semua kata kerja HTTP dengan konten : POST, PUT, DELETE dll. Meskipun Anda hanya dapat menggunakan POST dalam aplikasi Anda, lebih baik memiliki solusi umum dan memverifikasi bahwa semua data yang Anda terima dengan kata kerja apa pun memiliki anti-pemalsuan. token.
sumber
.ajaxSend()
menyatakan "Pada jQuery 1.8, metode .ajaxSend () hanya boleh dilampirkan ke dokumen." api.jquery.com/ajaxsendoptions
, yang tercantum dalamif
pernyataan akhir ? Terima kasih.Saya tahu ada banyak jawaban lain, tetapi artikel ini bagus dan ringkas dan memaksa Anda untuk memeriksa semua HttpPosts Anda, bukan hanya beberapa di antaranya:
http://richiban.wordpress.com/2013/02/06/validating-net-mvc-4-anti-forgery-tokens-in-ajax-requests/
Ia menggunakan tajuk HTTP alih-alih mencoba mengubah kumpulan formulir.
Server
Klien
sumber
Saya merasa seperti ahli nujum canggih di sini, tapi ini masih menjadi masalah 4 tahun kemudian di MVC5.
Untuk menangani permintaan ajax dengan benar, token anti-pemalsuan perlu diteruskan ke server pada panggilan ajax. Mengintegrasikannya ke dalam data dan model pos Anda berantakan dan tidak perlu. Menambahkan token sebagai header khusus bersih dan dapat digunakan kembali - dan Anda dapat mengonfigurasinya sehingga Anda tidak harus ingat untuk melakukannya setiap waktu.
Ada pengecualian - ajax tidak mengganggu tidak memerlukan perlakuan khusus untuk panggilan ajax. Token dilewatkan seperti biasa di bidang input tersembunyi biasa. Persis sama dengan POST biasa.
_Layout.cshtml
Di _layout.cshtml saya memiliki blok JavaScript ini. Itu tidak menulis token ke DOM, melainkan menggunakan jQuery untuk mengekstraknya dari literal input tersembunyi yang dihasilkan MVC Helper. String Ajaib yang merupakan nama header didefinisikan sebagai konstanta di kelas atribut.
Perhatikan penggunaan tanda kutip tunggal dalam fungsi beforeSend - elemen input yang dirender menggunakan tanda kutip ganda yang akan memecah literal JavaScript.
JavaScript klien
Ketika ini dijalankan, fungsi beforeSend di atas dipanggil dan AntiForgeryToken secara otomatis ditambahkan ke header permintaan.
Perpustakaan Server
Atribut khusus diperlukan untuk memproses token non standar. Ini dibangun di atas solusi @ viggity, tetapi menangani ajax yang tidak mencolok dengan benar. Kode ini dapat disimpan di perpustakaan umum Anda
Server / Pengendali
Sekarang Anda tinggal menerapkan atribut ke Action Anda. Lebih baik lagi Anda dapat menerapkan atribut ke controller Anda dan semua permintaan akan divalidasi.
sumber
$.ajaxSetup
untuk mendefinisikanbeforesend
eventhandler umum , dapat terjadi bahwa Anda menimpanya. Saya menemukan solusi lain di mana Anda dapat menambahkan penangan kedua yang juga akan dipanggil. Bekerja dengan baik dan tidak merusak implementasi Anda.Jangan gunakan Html.AntiForgeryToken . Alih-alih, gunakan AntiForgery.GetTokens dan AntiForgery.Validate dari Web API seperti yang dijelaskan dalam Mencegah Serangan Pemalsuan Permintaan Situs Lintas (CSRF) dalam Aplikasi ASP.NET MVC .
sumber
Saya baru saja mengimplementasikan masalah aktual ini dalam proyek saya saat ini. saya melakukannya untuk semua ajax-POST yang membutuhkan pengguna yang diautentikasi.
Pertama saya memutuskan untuk menghubungkan panggilan ajax jquery saya jadi saya tidak mengulangi diri saya terlalu sering. cuplikan javascript ini memastikan semua panggilan ajax (posting) akan menambahkan token validasi permintaan saya ke permintaan. Catatan: nama __RequestVerificationToken digunakan oleh .Net framework sehingga saya dapat memanfaatkan fitur Anti-CSRF standar seperti yang ditunjukkan di bawah ini.
Dalam Tampilan Anda di mana Anda memerlukan token yang tersedia untuk javascript di atas hanya menggunakan HTML-Helper umum. Anda pada dasarnya dapat menambahkan kode ini di mana pun Anda inginkan. Saya menempatkannya dalam pernyataan if (Request.IsAuthenticated):
Dalam controller Anda cukup gunakan mekanisme standar ASP.Net MVC Anti-CSRF. Saya melakukannya seperti ini (meskipun saya benar-benar menggunakan Garam).
Dengan Firebug atau alat serupa Anda dapat dengan mudah melihat bagaimana permintaan POST Anda sekarang memiliki parameter __RequestVerificationToken ditambahkan.
sumber
Saya pikir yang harus Anda lakukan adalah memastikan bahwa input "__RequestVerificationToken" termasuk dalam permintaan POST. Separuh informasi lainnya (yaitu token dalam cookie pengguna) sudah dikirim secara otomatis dengan permintaan POST AJAX.
Misalnya,
sumber
AntiForgeryToken
itu bisa diperdebatkan. Jika ya (tidak yakin bagaimana Anda mendapatkannya dalam kasus itu, tetapi dengan asumsi Anda), maka hal di atas akan berfungsi dengan baik. Jika Anda mencoba membuat halaman web sederhana yang akan memposting permintaan ke server yang mengharapkan token tersebut, dan server tidak menghasilkan halaman tersebut, maka Anda kurang beruntung. Itulah intinya AntiForgeryToken ...Anda juga dapat melakukan ini:
Ini menggunakan
Razor
, tetapi jika Anda menggunakanWebForms
sintaks Anda bisa menggunakan<%= %>
tagsumber
Lebih jauh lagi ke komentar saya terhadap jawaban @ JBall yang membantu saya sepanjang jalan, ini adalah jawaban terakhir yang bekerja untuk saya. Saya menggunakan MVC dan Razor dan saya mengirimkan formulir menggunakan jQuery AJAX sehingga saya dapat memperbarui tampilan parsial dengan beberapa hasil baru dan saya tidak ingin melakukan postback lengkap (dan flicker halaman).
Tambahkan
@Html.AntiForgeryToken()
dalam formulir seperti biasa.Kode tombol pengiriman AJAX saya (yaitu acara onclick) adalah:
Saya telah meninggalkan tindakan "sukses" karena ini menunjukkan bagaimana tampilan sebagian sedang diperbarui yang berisi MvcJqGrid dan bagaimana sedang di-refresh (kisi jqGrid yang sangat kuat dan ini adalah bungkus MVC yang brilian untuk itu).
Metode pengontrol saya terlihat seperti ini:
Saya harus mengakui untuk tidak menjadi penggemar POSTing seluruh data formulir sebagai Model tetapi jika Anda perlu melakukannya maka ini adalah salah satu cara yang bekerja. MVC hanya membuat pengikatan data terlalu mudah sehingga daripada mengirimkan 16 nilai individu (atau FormCollection yang diketik dengan lemah) ini OK, saya kira. Jika Anda lebih tahu, beri tahu saya karena saya ingin menghasilkan kode MVC C # yang kuat.
sumber
menemukan ide yang sangat pintar ini dari https://gist.github.com/scottrippey/3428114 untuk setiap $ .ajax panggilan yang memodifikasi permintaan dan menambahkan token.
sumber
if (options.contentType != false && options.contentType.indexOf('application/json') === 0) {
untuk menangkap panggilan Ajax yang belum menentukan jenis konten1.Tentukan Fungsi untuk mendapatkan Token dari server
2. Dapatkan token dan atur header sebelum mengirim ke server
3. Validasi Onserver pada HttpRequestBase pada metode yang Anda tangani Post / get
sumber
Saya sadar sudah beberapa waktu sejak pertanyaan ini diposting, tetapi saya menemukan sumber daya yang sangat berguna, yang membahas penggunaan AntiForgeryToken dan membuatnya lebih sulit untuk digunakan. Ini juga menyediakan plugin jquery untuk dengan mudah memasukkan token antiforgery dalam panggilan AJAX:
Resep Permintaan Anti-Pemalsuan Untuk ASP.NET MVC Dan AJAX
Saya tidak berkontribusi banyak, tetapi mungkin seseorang akan merasakan manfaatnya.
sumber
sumber
Inilah cara termudah yang pernah saya lihat. Catatan: Pastikan Anda memiliki "@ Html.AntiForgeryToken ()" di Tampilan Anda
sumber
Perbaikan sedikit ke solusi 360Airwalk. Ini menanamkan Token Anti Pemalsuan dalam fungsi javascript, jadi @ Html.AntiForgeryToken () tidak lagi perlu disertakan pada setiap tampilan.
sumber
sumber
Saya menggunakan posting ajax untuk menjalankan metode delete (kebetulan dari timeline visjs tapi itu bukan relelvant). Inilah yang saya sis:
Ini adalah Index.cshtml saya
Yang saya tambahkan di sini adalah
@Html.AntiForgeryToken()
untuk membuat token muncul di halamanKemudian di postingan ajax saya, saya menggunakan:
Yang menambahkan nilai token, dihapus dari halaman, ke bidang yang diposting
Sebelum ini saya mencoba meletakkan nilai di header tetapi saya mendapat kesalahan yang sama
Jangan ragu untuk mengirim peningkatan. Ini sepertinya merupakan pendekatan sederhana yang bisa saya mengerti
sumber
Oke banyak posting di sini, tidak ada satupun yang membantu saya, berhari-hari google, dan masih belum lagi saya sampai pada titik penulisan seluruh aplikasi dari awal, dan kemudian saya perhatikan nugget kecil ini di Web.confg saya
Sekarang saya tidak tahu mengapa saya menambahkannya, tetapi sejak itu saya perhatikan, diabaikan dalam mode debug dan tidak dalam mode produksi (IE Installed to IIS Somewhere)
Bagi saya solusinya adalah salah satu dari 2 pilihan, karena saya tidak ingat mengapa saya menambahkannya saya tidak bisa memastikan hal-hal lain tidak bergantung padanya, dan kedua nama domain harus semuanya huruf kecil dan TLD tidak seperti ive selesai di * .localLookup.net
Mungkin ini membantu, mungkin juga tidak. Saya harap itu membantu seseorang
sumber
Solusi yang saya temukan bukan untuk ASPX tetapi untuk Razor, tetapi masalah yang cukup bisa dilakukan.
Saya mengatasinya dengan menambahkan AntiForgery ke permintaan. Pembantu HTML tidak membuat id HTML dengan panggilan
Untuk menambahkan token ke postrequest, saya baru saja menambahkan id AntiForgery ke bidang tersembunyi dengan jquery:
Ini menyebabkan pengontrol menerima permintaan dengan atribut [ValidateAntiForgeryToken]
sumber
AntiforgeryToken masih menyakitkan, tidak ada satu pun contoh di atas yang berhasil kata demi kata untuk saya. Terlalu banyak untuk di sana. Jadi saya menggabungkan semuanya. Butuh @ Html.AntiforgeryToken dalam bentuk nongkrong di iirc
Dipecahkan seperti itu:
Jika ragu, tambahkan lebih banyak tanda $
sumber