Apa risiko keamanan pengaturan Access-Control-Allow-Origin?

124

Saya baru-baru harus ditetapkan Access-Control-Allow-Originuntuk *agar dapat melakukan panggilan ajax lintas subdomain.
Sekarang saya merasa bahwa saya menempatkan lingkungan saya pada risiko keamanan.
Tolong bantu saya jika saya salah melakukannya.

Hamed Momeni
sumber

Jawaban:

69

Dengan menanggapi dengan Access-Control-Allow-Origin: *, sumber daya yang diminta memungkinkan berbagi dengan setiap asal. Ini pada dasarnya berarti bahwa situs apa pun dapat mengirim permintaan XHR ke situs Anda dan mengakses respons server yang tidak akan menjadi masalah jika Anda tidak menerapkan respons CORS ini.

Jadi situs mana pun dapat mengajukan permintaan ke situs Anda atas nama pengunjung mereka dan memproses tanggapannya. Jika Anda menerapkan sesuatu seperti skema otentikasi atau otorisasi yang didasarkan pada sesuatu yang secara otomatis disediakan oleh browser (cookie, sesi berbasis cookie, dll.), Permintaan yang dipicu oleh situs pihak ketiga akan menggunakannya juga.

Ini memang menimbulkan risiko keamanan, terutama jika Anda mengizinkan berbagi sumber daya tidak hanya untuk sumber daya yang dipilih tetapi untuk setiap sumber daya. Dalam konteks ini, Anda harus melihat Kapan aman untuk mengaktifkan CORS? .

Gumbo
sumber
2
Jika Anda dapat memberikan contoh spesifik tentang bagaimana akses autentikasi bersama menimbulkan risiko keamanan, saya akan memberi suara positif.
Petrus Theron
1
@ Gumbo Bagaimana dengan konten statis? (mis. konten cdn statis, seperti javascripts, css, static htmls, dll.) Apakah ada masalah keamanan saat menyetelnya Access-Control-Allow-Origin: *? Tidak akan ada nogin dll, mereka terbuka untuk semua orang?
Umut Benzer
2
@UutBen Tidak apa-apa.
Gumbo
25
Sebenarnya jawaban ini tidak sepenuhnya benar menurut standar CORS saat ini : "String '*' tidak dapat digunakan untuk sumber daya yang mendukung kredensial." Jadi, Anda tidak dapat memaksa permintaan untuk menggunakan otentikasi sementara dalam bentuk cookie, otentikasi HTTP dalam cache atau sertifikat SSL klien. Namun jika situs web tersebut misalnya menggunakan penyimpanan lokal untuk otentikasi, itu akan menjadi masalah.
Niklas B.
2
@NiklasB: Saya mencoba skenario ini dan Chrome mengikuti standar CORS seperti yang Anda sebutkan. yaitu string " " tidak didukung dengan permintaan kredensial. Inilah yang dilaporkan oleh Chrome: "XMLHttpRequest tidak dapat memuat localhost: 12346 / hello . Karakter pengganti ' ' tidak dapat digunakan di header 'Access-Control-Allow-Origin' jika tanda kredensial benar. Asal ' localhost: 12345 ' oleh karena itu tidak diizinkan akses. Mode kredensial XMLHttpRequest dikontrol oleh atribut withCredentials. "
factotum
37

Access-Control-Allow-Origin: *benar-benar aman untuk ditambahkan ke sumber daya apa pun, kecuali sumber daya tersebut berisi data pribadi yang dilindungi oleh sesuatu selain kredensial standar (cookie, otorisasi dasar, sertifikat klien TLS).

Misalnya: Data yang dilindungi oleh cookie aman

Bayangkan https://example.com/users-private-data, yang mungkin mengekspos data pribadi tergantung pada status login pengguna. Status ini menggunakan cookie sesi. Anda dapat menambahkan sumber daya ini dengan amanAccess-Control-Allow-Origin: * , karena header ini hanya mengizinkan akses ke respons jika permintaan dibuat tanpa cookie, dan cookie diperlukan untuk mendapatkan data pribadi. Alhasil, tidak ada data pribadi yang bocor.

Misalnya: Data yang dilindungi oleh lokasi / ip / jaringan internal tidak aman (sayangnya umum terjadi pada intranet dan peralatan rumah tangga):

Bayangkan https://intranet.example.com/company-private-data, yang mengekspos data perusahaan swasta, tetapi ini hanya dapat diakses jika Anda berada di jaringan wifi perusahaan. Tidak aman menambahkan Access-Control-Allow-Origin: *sumber daya ini, karena dilindungi menggunakan sesuatu selain kredensial standar. Jika tidak, skrip yang buruk dapat menggunakan Anda sebagai terowongan ke intranet.

Aturan praktis

Bayangkan apa yang akan dilihat pengguna jika mereka mengakses sumber daya di jendela penyamaran. Jika Anda senang semua orang melihat konten ini (termasuk kode sumber yang diterima browser), Anda dapat menambahkannya dengan aman Access-Control-Allow-Origin: *.

JaffaTheCake
sumber
haruskah "karena hanya mengizinkan permintaan tanpa cookie" menjadi "karena hanya mengizinkan permintaan dengan cookie"?
DJCordhose
3
@DJ Access-Control-Allow-Origin: *hanya mengizinkan permintaan tanpa cookie. Saya telah mengedit jawabannya untuk sedikit menjelaskan.
JaffaTheCake
Apa perbedaan antara "*" dan case tanpa header ini sama sekali. Apakah itu sama?
Nigrimmist
Saya akan senang jika "Jika tidak, skrip yang buruk dapat menggunakan Anda sebagai terowongan ke intranet" dapat dijelaskan lebih lanjut.
Sam Rueby
@Nigrimmist Maka permintaan preflight akan gagal dan akses sumber daya akan diblokir
iamareebjamal
9

AFAIK, Access-Control-Allow-Origin hanyalah header http yang dikirim dari server ke browser. Membatasi ke alamat tertentu (atau menonaktifkannya) tidak membuat situs Anda lebih aman, misalnya untuk robot. Jika robot menginginkannya, mereka dapat mengabaikan headernya. Browser biasa di luar sana (Explorer, Chrome, dll.) Secara default menerima header. Tetapi aplikasi seperti Postman mengabaikannya begitu saja.

Ujung server tidak benar-benar memeriksa apa 'asal' dari permintaan saat mengembalikan respons. Itu hanya menambahkan header http. Ini adalah browser (ujung klien) yang mengirim permintaan yang memutuskan untuk membaca header kontrol akses dan menindaklanjutinya. Perhatikan bahwa dalam kasus XHR, mungkin menggunakan permintaan 'OPTIONS' khusus untuk meminta header terlebih dahulu.

Jadi, siapa pun dengan kemampuan skrip kreatif dapat dengan mudah mengabaikan keseluruhan header, apa pun yang diatur di dalamnya.

Lihat juga Masalah keamanan yang mungkin terjadi pada pengaturan Access-Control-Allow-Origin .


Sekarang untuk benar-benar menjawab pertanyaan itu

Saya tidak bisa tidak merasa bahwa saya menempatkan lingkungan saya pada risiko keamanan.

Jika ada yang ingin menyerang Anda, mereka dapat dengan mudah melewati Access-Control-Allow-Origin. Tetapi dengan mengaktifkan '*' Anda memberikan penyerang beberapa 'vektor serangan' lagi untuk dimainkan, seperti, menggunakan browser web biasa yang menghormati header HTTP itu.

commonpike
sumber
6
Lihatlah ini dari sudut pandang pengguna akhir yang tidak waspada. Seseorang dapat membuat halaman web berbahaya yang memasukkan JavaScript untuk melewatkan data antara situs asli dan situs jahat (katakanlah mereka ingin mencuri sandi Anda). Browser web pengguna akhir biasanya akan memblokir komunikasi lintas situs ini, tetapi jika Access-Control-Allow-Origin diatur, maka itu akan diizinkan, dan pengguna akhir tidak akan lebih bijak.
Brain2000
3
Ya, pengaturan Access-Control-Allow-Origin *di situs web berbahaya yang menginangi skrip untuk mencuri sandi sangat tidak disarankan :-)
commonpike
6
@commonpike Anda benar bahwa seseorang dapat membuat skrip untuk mengabaikan header sepenuhnya. Jika data dapat diakses, data dapat diakses dengan atau tanpa header CORS. Ada vektor serangan lain yang tidak Anda pertimbangkan. Misalkan saya masuk ke situs web bank saya. Jika saya pergi ke halaman lain dan kemudian kembali ke bank saya, saya masih login karena cookie. Pengguna lain di internet dapat membuka URL yang sama di bank saya seperti yang saya lakukan, namun mereka tidak dapat mengakses akun saya tanpa cookie. Jika permintaan lintas sumber diizinkan, situs web berbahaya dapat secara efektif meniru ...
Brad
5
@commonpike ... pengguna. Dengan kata lain, Anda mungkin mengunjungi situs saya (yang bahkan bisa menjadi situs biasa, tanpa ada yang mencurigakan ... mungkin itu adalah situs asli yang baru saja dibajak!) Tetapi beberapa JavaScript yang membuat permintaan HTTP ke bank Anda untuk mentransfer beberapa dana ke akun saya. Bank tidak mengetahui perbedaan antara permintaan dari halamannya atau permintaan dari halaman lain. Keduanya memiliki cookie yang memungkinkan permintaan berhasil.
Brad
3
@commonpike Izinkan saya memberi Anda contoh yang lebih umum ... yang terjadi sepanjang waktu. Misalkan Anda memiliki router rumah yang umum, seperti Linksys WRT54g atau semacamnya. Misalkan router memungkinkan permintaan lintas sumber. Skrip di halaman web saya dapat membuat permintaan HTTP ke alamat IP router umum (seperti 192.168.1.1) dan mengkonfigurasi ulang router Anda untuk memungkinkan serangan. Ia bahkan dapat menggunakan router Anda secara langsung sebagai node DDoS. (Sebagian besar router memiliki halaman uji yang memungkinkan ping atau pemeriksaan server HTTP sederhana. Ini dapat disalahgunakan secara massal.)
Brad
6

Berikut adalah 2 contoh yang diposting sebagai komentar, jika karakter pengganti benar-benar bermasalah:

Misalkan saya masuk ke situs web bank saya. Jika saya pergi ke halaman lain dan kemudian kembali ke bank saya, saya masih login karena cookie. Pengguna lain di internet dapat membuka URL yang sama di bank saya seperti yang saya lakukan, namun mereka tidak dapat mengakses akun saya tanpa cookie. Jika permintaan lintas sumber diizinkan, situs web berbahaya dapat secara efektif meniru identitas pengguna.

- Brad

Misalkan Anda memiliki router rumah umum, seperti Linksys WRT54g atau semacamnya. Misalkan router memungkinkan permintaan lintas sumber. Skrip di halaman web saya dapat membuat permintaan HTTP ke alamat IP router umum (seperti 192.168.1.1) dan mengkonfigurasi ulang router Anda untuk memungkinkan serangan. Ia bahkan dapat menggunakan router Anda secara langsung sebagai node DDoS. (Sebagian besar router memiliki halaman pengujian yang memungkinkan ping atau pemeriksaan server HTTP sederhana. Ini dapat disalahgunakan secara massal.)

- Brad

Saya merasa bahwa komentar ini seharusnya menjadi jawaban, karena menjelaskan masalah dengan contoh kehidupan nyata.

Christian Gollhardt
sumber
8
Kecuali ini tidak akan berhasil. "String '*' tidak dapat digunakan untuk sumber daya yang mendukung kredensial." w3.org/TR/cors/#resource-requests
bayo
@bayotop Bagaimana browser membedakan halaman yang memerlukan autentikasi dan halaman dengan data lain di header?
Rabu mulai
Setelah membaca tautan yang disediakan, ada "mendukung tanda kredensial" yang digunakan untuk tujuan ini. Tampaknya disetel secara manual, jadi mungkin jika seseorang tidak tahu cara menyiapkan CORS dengan benar, mereka juga bisa mendapatkan tanda ini salah, jadi saya yakin kerentanan di atas mungkin terjadi.
Rabu mulai
2
@wedrom Bendera ditetapkan oleh orang yang membuat permintaan. Bagaimanapun, skenario di atas adalah contoh serangan CSRF. Membiarkan asal '*' tidak akan membuat Anda lebih rentan daripada Anda (mungkin sedikit dalam kasus yang jarang terjadi). Dalam kebanyakan kasus, Anda dapat membuat permintaan lintas situs berbahaya menggunakan formulir sehingga CORS tidak menjadi masalah. Dalam kasus di mana Anda perlu melakukan permintaan AJAX, permintaan pra-penerbangan akan menghalangi (ini adalah titik di mana browser masuk ketika ACAO: '*' dan Access-Control-Allow-Credentials: 'true').
bayo
0

Dalam skenario di mana server mencoba untuk menonaktifkan CORS sepenuhnya dengan menyetel header di bawah ini.

  • Access-Control-Allow-Origin: * (memberi tahu browser bahwa server menerima permintaan lintas situs dari ASAL mana pun)

  • Access-Control-Allow-Credentials: true (memberi tahu browser bahwa permintaan lintas situs dapat mengirim cookie)

Ada keamanan gagal yang diterapkan di browser yang akan menghasilkan kesalahan di bawah ini

"Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’"

Jadi dalam kebanyakan skenario pengaturan 'Access-Control-Allow-Origin' *tidak akan menjadi masalah. Namun untuk mengamankan dari serangan, server dapat mempertahankan daftar asal yang diizinkan dan setiap kali server mendapatkan permintaan lintas sumber, ia dapat memvalidasi header ORIGIN terhadap daftar asal yang diizinkan dan kemudian menggemakannya kembali di Access-Control-Allow-Origin header.

Karena header ORIGIN tidak dapat diubah dengan javascript yang berjalan di browser, situs berbahaya tidak akan dapat memalsukannya.

shadow0359
sumber