Bagaimana cara kerja cookie HttpOnly dengan permintaan AJAX?

195

JavaScript membutuhkan akses ke cookie jika AJAX digunakan di situs dengan batasan akses berdasarkan cookie. Akankah HttpOnly cookie berfungsi di situs AJAX?

Sunting: Microsoft menciptakan cara untuk mencegah serangan XSS dengan melarang akses JavaScript ke cookie jika HttpOnly ditentukan. FireFox kemudian mengadopsi ini. Jadi pertanyaan saya adalah: Jika Anda menggunakan AJAX di situs, seperti StackOverflow, apakah cookie Http-Only pilihan?

Sunting 2: Pertanyaan 2. Jika tujuan HttpOnly adalah untuk mencegah akses JavaScript ke cookie, dan Anda masih dapat mengambil cookie melalui JavaScript melalui Objek XmlHttpRequest, apa gunanya HttpOnly ?

Sunting 3: Berikut ini adalah kutipan dari Wikipedia:

Saat browser menerima cookie seperti itu, ia seharusnya menggunakannya seperti biasa dalam pertukaran HTTP berikut, tetapi tidak membuatnya terlihat oleh skrip sisi klien. [32] The HttpOnlybendera bukan bagian dari standar apapun, dan tidak dilaksanakan di semua browser. Perhatikan bahwa saat ini tidak ada pencegahan membaca atau menulis cookie sesi melalui XMLHTTPRequest. [33].

Saya mengerti bahwa document.cookiediblokir ketika Anda menggunakan HttpOnly. Tetapi tampaknya Anda masih bisa membaca nilai cookie di objek XMLHttpRequest, memungkinkan untuk XSS. Bagaimana HttpOnly membuat Anda lebih aman daripada? Dengan membuat cookie pada dasarnya hanya baca?

Dalam contoh Anda, saya tidak bisa menulis ke Anda document.cookie, tetapi saya masih bisa mencuri cookie Anda dan mempostingnya ke domain saya menggunakan objek XMLHttpRequest.

<script type="text/javascript">
    var req = null;
    try { req = new XMLHttpRequest(); } catch(e) {}
    if (!req) try { req = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {}
    if (!req) try { req = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
    req.open('GET', 'http://stackoverflow.com/', false);
    req.send(null);
    alert(req.getAllResponseHeaders());
</script>

Sunting 4: Maaf, maksud saya Anda dapat mengirim XMLHttpRequest ke domain StackOverflow, dan kemudian menyimpan hasil getAllResponseHeaders () ke string, regex cookie, dan mempostingnya ke domain eksternal. Tampaknya Wikipedia dan ha.ckers setuju dengan saya tentang hal ini, tetapi saya ingin sekali dididik ulang ...

Edit Terakhir: Ahh, ternyata kedua situs salah, ini sebenarnya adalah bug di FireFox . IE6 & 7 sebenarnya adalah satu-satunya browser yang saat ini sepenuhnya mendukung HttpOnly.

Untuk mengulangi semua yang telah saya pelajari:

  • HttpOnly membatasi semua akses ke document.cookie di IE7 & dan FireFox (tidak yakin tentang browser lain)
  • HttpOnly menghapus informasi cookie dari header respons di XMLHttpObject.getAllResponseHeaders () di IE7.
  • XMLHttpObjects hanya dapat dikirimkan ke domain asal mereka, sehingga tidak ada posting lintas domain dari cookie.

sunting: Informasi ini kemungkinan tidak lagi terkini.

Shawn
sumber
Saya melemparkan contoh Anda dalam skrip greasemonkey dan sepertinya FF tidak lagi menampilkan cookie. Penelitian dan contoh luar biasa.
Mungkin dengan Kebijakan Asal yang Sama Anda tidak dapat membuat permintaan http ke domain yang tidak sama dengan skrip berjalan; namun, saya percaya bahwa Anda dapat dengan mudah mengirimkan cookie dengan mengarahkan ulang pengguna ke halaman menggunakan window.location dan meneruskan semua informasi melalui parameter string kueri.
Luca Marzi
@LucaMarzi " Anda tidak dapat membuat permintaan http ke domain yang tidak sama dengan script yang sedang berjalan di " Apakah Anda mengatakan bahwa situs X tidak dapat menyertakan gambar dari host Y? (fitur yang telah didukung oleh semua browser sejak Mosaic?)
curiousguy

Jawaban:

64

Ya, cookie HTTP-Only tidak masalah untuk fungsi ini. Mereka masih akan diberikan permintaan XmlHttpRequest ke server.

Dalam kasus Stack Overflow, cookie secara otomatis disediakan sebagai bagian dari permintaan XmlHttpRequest. Saya tidak tahu detail implementasi dari penyedia otentikasi Stack Overflow, tetapi data cookie itu mungkin secara otomatis digunakan untuk memverifikasi identitas Anda pada tingkat yang lebih rendah daripada metode pengontrol "vote".

Secara umum, cookie tidak diperlukan untuk AJAX. Dukungan XmlHttpRequest (atau bahkan iframe remoting, pada browser lama) adalah semua yang secara teknis diperlukan.

Namun, jika Anda ingin memberikan keamanan untuk fungsi yang diaktifkan AJAX, maka aturan yang sama berlaku seperti dengan situs tradisional. Anda memerlukan beberapa metode untuk mengidentifikasi pengguna di balik setiap permintaan, dan cookie hampir selalu merupakan sarana untuk tujuan itu.

Dalam contoh Anda, saya tidak bisa menulis ke document.cookie Anda, tetapi saya masih bisa mencuri cookie Anda dan mempostingnya ke domain saya menggunakan objek XMLHttpRequest.

XmlHttpRequest tidak akan membuat permintaan lintas-domain (untuk alasan yang persis Anda sentuh).

Anda biasanya dapat menyuntikkan skrip untuk mengirim cookie ke domain Anda menggunakan iframe remoting atau JSONP, tetapi kemudian HTTP-Only melindungi cookie itu lagi karena tidak dapat diakses.

Kecuali Anda telah mengompromikan StackOverflow.com di sisi server, Anda tidak akan dapat mencuri cookie saya.

Sunting 2: Pertanyaan 2. Jika tujuan Http-Only adalah untuk mencegah akses JavaScript ke cookie, dan Anda masih dapat mengambil cookie melalui JavaScript melalui Objek XmlHttpRequest, apa gunanya Http-Only?

Pertimbangkan skenario ini:

  • Saya menemukan jalan untuk menyuntikkan kode JavaScript ke halaman.
  • Jeff memuat halaman dan JavaScript berbahaya saya memodifikasi cookie-nya agar cocok dengan milikku.
  • Jeff mengirimkan jawaban bintang untuk pertanyaan Anda.
  • Karena dia mengirimkannya dengan data cookie saya bukan miliknya, jawabannya akan menjadi milik saya.
  • Anda memilih jawaban bintang "saya".
  • Akun saya yang sebenarnya mendapatkan intinya.

Dengan cookie HTTP-Only, langkah kedua tidak mungkin, sehingga mengalahkan upaya XSS saya.

Sunting 4: Maaf, maksud saya Anda dapat mengirim XMLHttpRequest ke domain StackOverflow, dan kemudian menyimpan hasil getAllResponseHeaders () ke string, regex cookie, dan mempostingnya ke domain eksternal. Tampaknya Wikipedia dan ha.ckers setuju dengan saya tentang hal ini, tetapi saya ingin sekali dididik ulang ...

Itu benar. Anda masih bisa membajak sesi seperti itu. Itu secara signifikan menipiskan kawanan orang yang dapat dengan sukses mengeksekusi bahkan XSS yang meretas Anda sekalipun.

Namun, jika Anda kembali ke skenario contoh saya, Anda dapat melihat di mana HTTP-Only tidak berhasil memotong serangan XSS yang mengandalkan memodifikasi cookie klien (tidak umum).

Itu bermuara pada fakta bahwa a) tidak ada perbaikan tunggal akan memecahkan semua kerentanan dan b) tidak ada sistem akan pernah benar-benar aman. HTTP-Only adalah alat yang berguna dalam menopang XSS.

Demikian pula, meskipun pembatasan lintas domain pada XmlHttpRequest tidak 100% berhasil dalam mencegah semua eksploitasi XSS, Anda tetap tidak pernah bermimpi untuk menghapus pembatasan tersebut.

Dave Ward
sumber
Banyak kerangka kerja menempatkan csrf token di cookie . Saya kira panggilan AJAX yang membutuhkan csrfpemeriksaan tidak akan berfungsi kecuali jika Anda menempatkan token csrf di elemen HTML tersembunyi agar JS dapat mengambilnya.
pengguna
4

Belum tentu, itu tergantung apa yang ingin Anda lakukan. Bisakah Anda menguraikan sedikit? AJAX tidak memerlukan akses ke cookie untuk bekerja, AJAX dapat membuat permintaan sendiri untuk mengekstraksi informasi, permintaan halaman yang dibuat oleh panggilan AJAX dapat mengakses data cookie & meneruskannya kembali ke skrip panggilan tanpa Javascript harus secara langsung mengakses kue

Glenn Slaven
sumber
4

Ya, mereka adalah opsi yang layak untuk situs berbasis Ajax. Cookies otentikasi bukan untuk manipulasi oleh skrip, tetapi hanya disertakan oleh browser pada semua permintaan HTTP yang dibuat ke server.

Skrip tidak perlu khawatir tentang apa yang dikatakan cookie sesi - selama Anda diautentikasi, maka setiap permintaan ke server yang diprakarsai oleh pengguna atau skrip akan menyertakan cookie yang sesuai. Fakta bahwa skrip tidak dapat mengetahui sendiri isi cookie tidak penting.

Untuk cookie apa pun yang digunakan untuk tujuan selain otentikasi, ini dapat ditetapkan tanpa flag HTTP saja, jika Anda ingin skrip dapat memodifikasi atau membaca ini. Anda dapat memilih dan memilih cookie mana yang harus menjadi HTTP saja, jadi misalnya apa pun yang tidak sensitif seperti preferensi UI (urutan, runtuh panel tangan kiri atau tidak) dapat dibagikan dalam cookie dengan skrip.

Saya sangat suka cookie HTTP saja - itu salah satu ekstensi browser miliknya yang merupakan ide yang sangat rapi.

thomasrutter
sumber
3

Ada sedikit lebih dari ini.

Ajax tidak benar-benar membutuhkan cookie, tetapi mereka dapat berguna seperti poster lain sebutkan. Menandai cookie HTTPOnly untuk menyembunyikannya dari skrip hanya berfungsi sebagian, karena tidak semua browser mendukungnya, tetapi juga karena ada solusi umum.

Aneh bahwa header respons XMLHTTP memberikan cookie, secara teknis server tidak harus mengembalikan cookie dengan respons. Setelah disetel pada klien, ia tetap disetel hingga berakhir. Meskipun ada skema di mana cookie diubah dengan setiap permintaan untuk mencegah penggunaan kembali. Jadi, Anda mungkin dapat menghindari solusi tersebut dengan mengubah server untuk tidak menyediakan cookie pada respons XMLHTTP.

Secara umum, saya pikir HTTPOnly harus digunakan dengan hati-hati. Ada serangan skrip lintas situs tempat penyerang mengatur agar pengguna mengirimkan permintaan seperti ajax yang berasal dari situs lain, menggunakan formulir pos sederhana, tanpa menggunakan XMLHTTP, dan cookie yang masih aktif di browser Anda akan mengotentikasi permintaan tersebut.

Jika Anda ingin memastikan bahwa permintaan AJAX diautentikasi, permintaan itu sendiri DAN header HTTP harus berisi cookie. Misalnya melalui penggunaan skrip atau input tersembunyi unik. HTTPOnly akan menghalangi itu.

Biasanya alasan menarik untuk menginginkan HTTPOnly adalah untuk mencegah konten pihak ketiga yang disertakan pada halaman web Anda mencuri cookie. Tetapi ada banyak alasan menarik untuk sangat berhati-hati dalam memasukkan konten pihak ketiga, dan memfilternya secara agresif.

davenpcj
sumber
1

Cookie secara otomatis ditangani oleh browser saat Anda membuat panggilan AJAX, jadi Javascript Anda tidak perlu dipusingkan dengan cookie.

pkchukiss
sumber
1

Karena itu saya mengasumsikan JavaScript membutuhkan akses ke cookie Anda.

Semua permintaan HTTP dari browser Anda mengirimkan informasi cookie Anda ke situs yang dimaksud. JavaScript dapat mengatur dan membaca cookie. Cookie tidak menurut definisi yang diperlukan untuk aplikasi Ajax, tetapi cookie diperlukan untuk sebagian besar aplikasi web untuk mempertahankan status pengguna.

Jawaban formal untuk pertanyaan Anda sebagai ungkapan - "Apakah JavaScript perlu akses ke cookie jika AJAX digunakan?" - Oleh karena itu "tidak". Pikirkan bidang pencarian yang ditingkatkan yang menggunakan permintaan Ajax untuk memberikan opsi saran otomatis, misalnya. Tidak perlu informasi cookie dalam kasus itu.

Polsonby
sumber
XmlHttpRequest membutuhkan cookie. Pencarian yang disempurnakan yang Anda sebutkan mungkin berada di belakang halaman login. Tetapi apakah Javascript perlu atau tidak dapat mengekspos nilai cookie ke VM adalah pertanyaan yang berbeda.
Mr. Shiny dan New New 宇
1

Sebagai klarifikasi - dari sudut pandang server, halaman yang diminta oleh permintaan AJAX pada dasarnya tidak berbeda dengan permintaan HTTP standar yang dilakukan oleh pengguna dengan mengklik tautan. Semua properti permintaan normal: agen-pengguna, ip, sesi, cookie, dll. Diteruskan ke server.

Glenn Slaven
sumber
"Sesi" bukan konsep HTTP. Ini adalah konsep tingkat tinggi yang dibangun di atas konsep HTTP oleh suatu kerangka kerja.
curiousguy
0

Tidak, halaman yang permintaan panggilan AJAX juga memiliki akses ke cookie & itulah yang memeriksa apakah Anda login.

Anda dapat melakukan otentikasi lain dengan Javascript, tetapi saya tidak akan mempercayainya, saya selalu lebih suka meletakkan segala jenis otentikasi memeriksa di back-end.

Glenn Slaven
sumber
0

Ya, cookie sangat berguna untuk Ajax.

Memasukkan otentikasi ke URL permintaan adalah praktik yang buruk. Ada item berita minggu lalu tentang mendapatkan token otentikasi di URL dari cache Google.

Tidak, tidak ada cara untuk mencegah serangan. Browser lama masih memungkinkan akses sepele ke cookie melalui javascript. Anda dapat mem-bypass http saja, dll. Apa pun yang Anda dapatkan bisa didapat dengan upaya yang cukup. Kuncinya adalah membuatnya terlalu banyak upaya untuk menjadi berharga.

Jika Anda ingin membuat situs Anda lebih aman (tidak ada keamanan yang sempurna) Anda bisa menggunakan cookie otentikasi yang kedaluwarsa. Kemudian, jika cookie dicuri, penyerang harus menggunakannya sebelum kedaluwarsa. Jika tidak, maka Anda memiliki indikasi yang baik bahwa ada aktivitas mencurigakan di akun itu. Semakin pendek waktu jendela semakin baik untuk keamanan tetapi semakin banyak beban yang diletakkan pada server Anda menghasilkan dan memelihara kunci.

Jay
sumber