Berbagi sumber daya silang adalah mekanisme yang memungkinkan halaman web untuk membuat XMLHttpRequests ke domain lain (dari wikipedia ).
Saya telah mengutak-atik CORS selama beberapa hari terakhir dan saya pikir saya memiliki pemahaman yang cukup baik tentang bagaimana semuanya bekerja.
Jadi pertanyaan saya bukan tentang bagaimana CORS / preflight bekerja, ini tentang alasan di balik munculnya preflight sebagai tipe permintaan baru . Saya gagal melihat alasan mengapa server A perlu mengirim preflight (PR) ke server B hanya untuk mengetahui apakah permintaan nyata (RR) akan diterima atau tidak - tentu saja akan mungkin bagi B untuk menerima / menolak RR tanpa PR sebelumnya.
Setelah mencari sedikit saya menemukan sepotong informasi di www.w3.org (7.1.5):
Untuk melindungi sumber daya terhadap permintaan lintas-asal yang tidak dapat berasal dari agen pengguna tertentu sebelum spesifikasi ini ada, permintaan preflight dibuat untuk memastikan bahwa sumber daya mengetahui spesifikasi ini.
Saya menemukan ini adalah kalimat paling sulit untuk dipahami. Interpretasi saya (lebih baik menyebutnya 'tebakan terbaik') adalah tentang melindungi server B terhadap permintaan dari server C yang tidak mengetahui spesifikasi.
Bisakah seseorang menjelaskan skenario / menunjukkan masalah yang PR + RR memecahkan lebih baik daripada RR saja?
Apa motivasi di balik memperkenalkan permintaan preflight?
Permintaan Preflight diperkenalkan sehingga browser dapat yakin itu berurusan dengan server yang menyadari CORS sebelum mengirim permintaan tertentu. Permintaan tersebut didefinisikan sebagai permintaan yang berpotensi berbahaya (perubahan negara) dan baru (tidak mungkin dilakukan sebelum CORS karena Kebijakan Asal yang Sama ). Menggunakan permintaan preflight berarti bahwa server harus ikut serta (dengan merespons dengan baik pada preflight) untuk jenis permintaan baru yang berpotensi berbahaya yang dimungkinkan oleh CORS.
Itulah arti dari bagian spesifikasi ini : "Untuk melindungi sumber daya terhadap permintaan lintas-asal yang tidak dapat berasal dari agen pengguna tertentu sebelum spesifikasi ini ada, permintaan preflight dibuat untuk memastikan bahwa sumber daya mengetahui spesifikasi ini."
Bisakah Anda memberi saya contoh?
Mari kita bayangkan bahwa pengguna browser masuk ke situs perbankan mereka di
A.com
. Ketika mereka menavigasi ke maliciousB.com
, halaman itu menyertakan beberapa Javascript yang mencoba mengirimDELETE
permintaanA.com/account
. Karena pengguna masuk keA.com
, permintaan itu, jika dikirim, akan termasuk cookie yang mengidentifikasi pengguna.Sebelum CORS, Kebijakan Asal Sama browser akan memblokirnya dari mengirimkan permintaan ini. Tetapi karena tujuan CORS adalah untuk memungkinkan komunikasi lintas asal semacam ini menjadi mungkin, itu tidak lagi sesuai.
Peramban dapat dengan mudah mengirim
DELETE
dan membiarkan server memutuskan bagaimana menanganinya. Tetapi bagaimana jikaA.com
tidak mengetahui protokol CORS? Itu mungkin pergi dan mengeksekusi yang berbahayaDELETE
. Mungkin diasumsikan bahwa — karena Kebijakan Same Origin dari peramban — ia tidak akan pernah bisa menerima permintaan seperti itu, dan karenanya mungkin tidak akan pernah diperketat terhadap serangan semacam itu.Untuk melindungi server yang tidak menyadari CORS, protokol memerlukan browser untuk terlebih dahulu mengirim permintaan preflight . Jenis permintaan baru ini adalah sesuatu yang hanya dapat ditanggapi oleh server yang sadar dengan CORS, memungkinkan peramban mengetahui apakah aman mengirim yang sebenarnya atau tidak
DELETE
.Mengapa semua ini ribut tentang browser, tidak bisa penyerang hanya mengirim
DELETE
permintaan dari komputer mereka sendiri?Tentu, tetapi permintaan seperti itu tidak akan menyertakan cookie pengguna. Serangan yang dirancang untuk mencegah hal ini bergantung pada fakta bahwa browser akan mengirim cookie (khususnya, informasi otentikasi untuk pengguna) untuk domain lain bersama dengan permintaan.
Itu terdengar seperti Cross-Site Request Pemalsuan , di mana formulir di situs
B.com
dapatPOST
untukA.com
dengan cookie pengguna dan melakukan kerusakan.Betul. Cara lain untuk menempatkan ini adalah bahwa permintaan preflight dibuat agar tidak meningkatkan permukaan serangan CSRF untuk server yang tidak menyadari CORS.
Tetapi melihat persyaratan untuk permintaan "sederhana" yang tidak memerlukan preflight, saya melihat bahwa
POST
itu masih diperbolehkan. Itu dapat mengubah status dan menghapus data sepertiDELETE
!Itu benar! CORS tidak melindungi situs Anda dari serangan CSRF. Kemudian lagi, tanpa CORS Anda juga tidak terlindungi dari serangan CSRF. Tujuan permintaan preflight adalah hanya untuk membatasi paparan CSRF Anda dengan apa yang sudah ada di dunia pra-CORS.
Mendesah. OK, saya dengan enggan menerima kebutuhan untuk permintaan preflight. Tetapi mengapa kita harus melakukannya untuk setiap sumber daya (URL) di server? Server menangani CORS atau tidak.
Apa kamu yakin akan hal itu? Tidak jarang banyak server menangani permintaan untuk satu domain. Sebagai contoh, itu mungkin kasus yang meminta untuk
A.com/url1
ditangani oleh satu jenis server dan permintaan untukA.com/url2
ditangani oleh jenis server yang berbeda. Ini umumnya bukan kasus bahwa server yang menangani sumber daya tunggal dapat membuat jaminan keamanan tentang semua sumber daya di domain itu.Baik. Mari berkompromi. Mari kita buat header CORS baru yang memungkinkan server untuk menyatakan dengan tepat sumber daya apa yang dapat berbicara, sehingga permintaan preflight tambahan untuk URL tersebut dapat dihindari.
Ide bagus! Bahkan, tajuk
Access-Control-Policy-Path
itu diusulkan hanya untuk tujuan ini. Namun, pada akhirnya, itu tidak termasuk dalam spesifikasi, tampaknya karena beberapa server salah menerapkan spesifikasi URI sedemikian rupa sehingga permintaan untuk jalur yang tampaknya aman untuk browser sebenarnya tidak aman di server yang rusak.Apakah ini keputusan bijaksana yang mengutamakan keamanan daripada kinerja, yang memungkinkan browser untuk segera mengimplementasikan spesifikasi CORS tanpa menempatkan server yang ada dalam risiko? Atau apakah itu picik untuk menghancurkan internet untuk memboroskan bandwidth dan menggandakan latensi hanya untuk mengakomodasi bug di server tertentu pada waktu tertentu?
Pendapat berbeda.
Ya, setidaknya browser akan menyimpan cache preflight untuk satu URL?
Iya. Meskipun mungkin tidak terlalu lama. Di browser WebKit, waktu cache preflight maksimum saat ini adalah 10 menit .
Mendesah. Nah, jika saya tahu bahwa server saya sadar CORS, dan karena itu tidak memerlukan perlindungan yang ditawarkan oleh permintaan preflight, apakah ada cara bagi saya untuk menghindarinya?
Satu-satunya pilihan nyata Anda adalah memastikan bahwa Anda memenuhi persyaratan untuk permintaan "sederhana". Itu mungkin berarti mengabaikan tajuk ubahsuaian yang akan Anda sertakan (seperti
X-Requested-With
), berbohong tentangContent-Type
, atau lebih.Apa pun yang Anda lakukan, Anda harus memastikan bahwa Anda memiliki perlindungan CSRF yang tepat karena spesifikasi CORS tidak membahas penolakan permintaan "sederhana", termasuk yang tidak aman
POST
. Seperti yang dinyatakan dalam spesifikasinya : "sumber daya yang permintaan sederhananya memiliki arti penting selain pengambilan harus melindungi diri dari Pemalsuan Permintaan Lintas Situs".sumber
Pertimbangkan dunia permintaan lintas domain sebelum CORS. Anda bisa melakukan bentuk POST standar, atau menggunakan
script
atauimage
tag untuk mengeluarkan permintaan GET. Anda tidak bisa membuat jenis permintaan lain selain GET / POST, dan Anda tidak bisa mengeluarkan header khusus apa pun pada permintaan ini.Dengan munculnya CORS, penulis spec dihadapkan dengan tantangan memperkenalkan mekanisme lintas domain baru tanpa melanggar semantik web yang ada. Mereka memilih untuk melakukan ini dengan memberikan server cara untuk ikut serta ke jenis permintaan baru apa pun. Keikutsertaan ini adalah permintaan preflight.
Jadi, DAPATKAN / POST permintaan tanpa header kustom tidak perlu preflight, karena permintaan ini sudah mungkin sebelum CORS. Tapi setiap permintaan dengan header kustom, atau permintaan PUT / DELETE, jangan perlu preflight, karena ini baru ke CORS spec. Jika server tidak tahu apa-apa tentang CORS, server akan membalas tanpa header spesifik CORS, dan permintaan sebenarnya tidak akan dibuat.
Tanpa permintaan preflight, server dapat mulai melihat permintaan tak terduga dari browser. Ini dapat menyebabkan masalah keamanan jika server tidak siap untuk jenis permintaan ini. Prelight CORS memungkinkan permintaan lintas domain untuk diperkenalkan ke web dengan cara yang aman.
sumber
CORS memungkinkan Anda menentukan lebih banyak tajuk dan tipe metode dari yang sebelumnya dimungkinkan dengan asal-usul silang
<img src>
atau<form action>
.Beberapa server dapat (dengan buruk) dilindungi dengan asumsi bahwa browser tidak dapat membuat, mis.
DELETE
Permintaan lintas asal atau permintaan lintas asal denganX-Requested-With
header, sehingga permintaan semacam itu "tepercaya".Untuk memastikan bahwa server benar-benar sangat mendukung CORS dan tidak hanya menanggapi permintaan acak, preflight dijalankan.
sumber
Berikut cara lain untuk melihatnya, menggunakan kode:
Sebelum CORS, upaya eksploitasi di atas akan gagal karena melanggar kebijakan yang sama-asal. API yang dirancang dengan cara ini tidak memerlukan perlindungan XSRF, karena dilindungi oleh model keamanan asli browser. Tidak mungkin peramban pra-CORS untuk menghasilkan JSON POST lintas-asal.
Sekarang CORS hadir - jika memilih ikut CORS melalui pra-penerbangan tidak diperlukan, tiba-tiba situs ini akan memiliki kerentanan besar, bukan karena kesalahan mereka sendiri.
Untuk menjelaskan mengapa beberapa permintaan diizinkan untuk melewati pra-penerbangan, ini dijawab oleh spek:
Untuk mengatasinya, GET tidak pra-penerbangan karena ini adalah "metode sederhana" seperti yang didefinisikan oleh 7.1.5. (Tajuk juga harus "sederhana" untuk menghindari pra-penerbangan). Pembenaran untuk ini adalah bahwa permintaan GET lintas-asal "sederhana" sudah bisa dilakukan oleh mis
<script src="">
(ini adalah cara kerja JSONP). Karena setiap elemen dengansrc
atribut dapat memicu GET lintas-asal, tanpa pra-penerbangan, tidak akan ada manfaat keamanan untuk memerlukan pra-pertarungan pada XHR "sederhana".sumber
Saya merasa bahwa jawaban yang lain tidak fokus pada alasan pra-pertarungan meningkatkan keamanan.
Skenario:
1) Dengan pra-penerbangan . Seorang penyerang memalsukan permintaan dari situs dummy-forums.com sementara pengguna diautentikasi ke safe-bank.com
Jika Server tidak memeriksa asal, dan entah bagaimana memiliki cacat, browser akan mengeluarkan permintaan pra-penerbangan, OPTION metode. Server tidak mengetahui bahwa CORS yang diharapkan oleh browser sebagai respons sehingga browser tidak akan melanjutkan (tidak ada salahnya)
2) Tanpa pra-penerbangan . Seorang penyerang memalsukan permintaan dalam skenario yang sama seperti di atas, browser akan mengeluarkan permintaan POST atau PUT segera, server menerimanya dan mungkin memprosesnya, ini berpotensi akan menyebabkan kerusakan.
Jika penyerang mengirim permintaan secara langsung, asal silang, dari beberapa host acak, kemungkinan besar orang memikirkan permintaan tanpa otentikasi. Itu permintaan palsu, tapi bukan permintaan xsrf. sehingga server telah akan memeriksa kredensial dan gagal. CORS tidak berusaha mencegah penyerang yang memiliki kredensial untuk mengeluarkan permintaan, meskipun daftar putih dapat membantu mengurangi vektor serangan ini.
Mekanisme pra-penerbangan menambah keamanan dan konsistensi antara klien dan server. Saya tidak tahu apakah ini sepadan dengan jabat tangan ekstra untuk setiap permintaan karena caching sangat bisa digunakan di sana, tapi begitulah cara kerjanya.
sumber
Sumber
sumber
Permintaan pra-penerbangan diperlukan untuk permintaan yang dapat mengubah status di server. Ada 2 jenis permintaan -
1) Panggilan yang tidak dapat mengubah status di server (seperti MENDAPATKAN) - Pengguna mungkin mendapatkan respons untuk permintaan (jika server tidak memeriksa keaslian) tetapi jika domain yang meminta tidak ditambahkan ke header respons Access-Control- Izinkan-Asal, browser tidak menampilkan data kepada pengguna, yaitu permintaan dikirim dari browser tetapi pengguna tidak dapat melihat / memanfaatkan respons.
2) Panggilan yang dapat mengubah status di server (seperti POST, HAPUS) - Karena dalam 1), kita melihat bahwa browser tidak memblokir permintaan tetapi responsnya, menyatakan panggilan yang berubah tidak boleh dilakukan tanpa pemeriksaan sebelumnya . Panggilan semacam itu mungkin membuat perubahan pada server yang dapat dipercaya yang tidak memeriksa asal-usul panggilan (disebut Pemalsuan Permintaan Situs Lintas), meskipun respons terhadap browser mungkin gagal. Untuk alasan ini, kami memiliki konsep permintaan pra-penerbangan yang melakukan panggilan PILIHAN sebelum setiap perubahan panggilan negara dapat dikirim ke server.
sumber
Bukankah permintaan sebelumnya tentang Kinerja ? Dengan permintaan preflighted, klien dapat dengan cepat mengetahui apakah operasi diizinkan sebelum mengirim sejumlah besar data, misalnya, di JSON dengan metode PUT. Atau sebelum melakukan perjalanan data sensitif dalam header otentikasi melalui kabel.
Fakta PUT, DELETE, dan metode lain, selain tajuk khusus, tidak diizinkan secara default (Mereka membutuhkan izin eksplisit dengan "Metode Akses-Kontrol-Permintaan" dan "Akses-Kontrol-Permintaan-Header"), yang berbunyi seperti pemeriksaan ulang, karena operasi ini dapat memiliki lebih banyak implikasi pada data pengguna, bukan MENDAPATKAN permintaan. Jadi, sepertinya:
"Saya melihat bahwa Anda mengizinkan permintaan lintas situs dari http: //foo.example , TAPI Anda PASTI akan mengizinkan permintaan DELETE? Apakah Anda mempertimbangkan dampak yang mungkin ditimbulkan oleh permintaan ini dalam data pengguna?"
Saya tidak mengerti korelasi yang dikutip antara permintaan preflighted dan manfaat server lama. Layanan Web yang diterapkan sebelum CORS, atau tanpa kesadaran CORS, tidak akan pernah menerima permintaan lintas situs APAPUN, karena pertama-tama respons mereka tidak akan memiliki tajuk "Akses-Kontrol-Izinkan-Asal".
sumber
Dalam browser yang mendukung CORS, permintaan membaca (seperti GET) sudah dilindungi oleh kebijakan asal-sama: Situs web jahat yang mencoba membuat permintaan lintas-domain yang diautentikasi (misalnya ke situs web internet banking korban atau antarmuka konfigurasi router) tidak akan dapat membaca data yang dikembalikan karena bank atau router tidak mengatur
Access-Control-Allow-Origin
header.Namun, dengan permintaan penulisan (seperti POST) kerusakan dilakukan ketika permintaan tiba di server web. * Server web dapat memeriksa
Origin
header untuk menentukan apakah permintaan tersebut sah, tetapi pemeriksaan ini sering tidak dilaksanakan karena server web tidak perlu untuk CORS atau server web lebih tua dari CORS dan karena itu mengasumsikan bahwa POST lintas domain sepenuhnya dilarang oleh kebijakan asal-sama.Itulah sebabnya webservers diberi kesempatan untuk ikut serta dalam menerima permintaan menulis lintas-domain .
* Pada dasarnya versi AJAX dari CSRF.
sumber