Mengurangi Pemalsuan Request CSRF Express.js (Pembuatan Menggunakan Cookie Situs Yang Sama) - CRUDPRO

Mengurangi Pemalsuan Request CSRF Express.js (Pembuatan Menggunakan Cookie Situs Yang Sama)

Express 4.14.0 telah dirilis. Ini akan memberikan pembaruan yang membuatnya lebih mudah untuk bertahan melawan Cross-Site Request Forgery (CSRF). Dalam posting ini, saya akan memberi Anda gambaran umum tentang CSRF, menjelaskan mekanisme pertahanan masa lalu, dan akhirnya menunjukkan cara menggunakan fitur Cookie Situs Sama yang baru dari Express.

CSRF adalah salah satu kerentanan aplikasi web yang paling umum dan mudah dieksploitasi. Sebagian alasan mengapa hal itu begitu umum adalah, sejujurnya, bahwa sebagian besar teknik mitigasi sulit diterapkan dan mudah membuat kesalahan. Tapi sebelum kita masuk ke situ, kita perlu meninjau CSRF.

Saat ini, ada berbagai cara untuk menyimpan dan mengirim data otentikasi, tetapi cookie sesi masih sangat populer, dan sayangnya, perbedaan halus dalam cara kerja cookie membuat CSRF bekerja. Setelah ditetapkan, cookie dikirim dengan setiap permintaan yang dikirimkan browser ke domain asli. Masalahnya adalah bahwa server hanya mengonfirmasi bahwa kumpulan cookie example.com yang terdapat dalam permintaan ke example.com telah dibaca dari example.com dan dikirim oleh HTML yang dikendalikan oleh example.com. Tidak mungkin. Intinya, CSRF adalah cara untuk membajak kepercayaan yang dimiliki server dalam menanggapi permintaan dari browser pengguna.

Salah satu contoh umum dari ini adalah untuk router rumah. Saat Anda mengunjungi situs web yang tidak tepercaya, situs web tersebut mengirimkan permintaan kepada browser untuk menambahkan pengguna baru ke router rumah Anda atas nama Anda. Browser mematuhi ini dan berisi cookie sesi dan permintaan yang diterima setelah login sebelumnya, yang membahayakan router.

Sekarang mari kita bicara tentang pencegahan CSRF, terutama pada aplikasi yang ditulis di node.js. Tidak seperti serangan seperti skrip lintas situs, ada banyak skema dan sistem berbeda yang telah digunakan untuk mencegah CSRF, dan tidak semuanya sama. Berikut adalah beberapa cara paling umum untuk mencegah CSRF:

1. Token anti CSRF

Token anti-CSRF adalah nomor acak yang aman secara kriptografis, ditautkan ke ID sesi, dan harus dikirim dengan semua permintaan kecuali GET di lokasi yang tidak dikirim secara otomatis. Parameter terbaik adalah parameter header atau badan permintaan, tetapi juga bisa berupa string kueri. Parameter juga digunakan. Token ini divalidasi oleh server setelah menerima permintaan dan memverifikasi bahwa itu cocok dengan token yang disimpan di sesi terkait. Ini adalah cara yang aman untuk mencegah CSRF jika diterapkan sepenuhnya. Kelemahan utamanya adalah tidak hanya melelahkan dan memakan waktu untuk diterapkan, tetapi juga cenderung kekurangan rute dan tetap tidak terlindungi.

2. Double Submit naive

Double submit naive adalah metode di mana nilai yang tidak dapat diperkirakan dikirim sebagai cookie dan parameter badan permintaan atau parameter string kueri. Setelah menerima permintaan, server memverifikasi bahwa kedua nilai sama sebelum melanjutkan. Metode ini hanya memiliki kemampuan untuk mengirim permintaan lintas situs melalui halaman HTML yang dihosting di domain lain, dengan asumsi penyerang tidak mengeksekusi JavaScript di domain atau subdomain target, tergantung pada apa yang Anda lakukan. Sebagai "naive". Buat terlalu banyak asumsi tentang batas penyerang. Ini mudah karena penyerang hanya perlu menjalankan javascript pada domain atau subdomain target, menulis cookie yang berisi nilai yang diketahui penyerang, dan mengirimkannya dengan vektor CSRF. Akan dinonaktifkan. Oleh karena itu, ini umum digunakan, tetapi tidak aman dan sebaiknya dihindari.

3. Pemeriksaan perujuk

Pemeriksaan perujuk adalah metode perlindungan CSRF yang bergantung pada tajuk pengarah yang dikirim dengan permintaan dari browser ke server untuk memastikan bahwa domain di tajuk cocok dengan domain yang ditentukan di tajuk HOST permintaan. Ada dua poin penting untuk mendapatkan metode ini dengan benar. Salah satunya adalah jika perujuk kosong atau tidak ada, Anda harus menolak permintaan tersebut. Ada berbagai cara untuk menghapus header perujuk secara permanen dari permintaan, seperti membuat permintaan dari halaman yang diakses melalui HTTPS. Kedua, metode yang digunakan untuk membandingkan header perujuk dan header HOST (biasanya ekspresi reguler) sama persis. Untuk ekspresi reguler, ini dalam bentuk ekspresi reguler berlabuh, sehingga permintaan yang berasal dari penyerang-contoh.com tidak akan cocok dengan permintaan yang dikirim ke contoh.com. Pada akhirnya, metode ini aman jika diterapkan dengan benar, tetapi ini bukan solusi yang paling kuat.

4. JSON-Web-Tokens (JWT)/Bearer Tokens:

Ini bisa dibilang salah satu cara terbaik untuk mencegah CSRF. Mekanisme dasarnya sederhana. Jangan gunakan cookie untuk menyimpan sesi Anda. Sebagai gantinya, nilai yang disimpan di penyimpanan lokal atau penyimpanan sesi (seperti JWT) digunakan dan dikirim sebagai header pada setiap permintaan. Kerugian dari metode ini adalah semua permintaan harus dikirim melalui XHR. Ini bukan masalah dalam aplikasi web satu halaman modern, tetapi dalam aplikasi lama yang ditulis dalam HTML murni, menerapkan metode ini bukanlah tugas yang mudah.

Metode ini bekerja dengan baik, kecuali untuk Double Submit naive. Selain itu, dari banyak aplikasi web dan kerangka kerja yang diaudit oleh tim Lift, hanya sedikit yang tidak menyadari bahwa CSRF merupakan masalah. Namun, persentase aplikasi tanpa perlindungan CSRF sangat tinggi.

Dan sebagai developer, kami memahami alasannya. Memikirkan perlunya menerapkan perlindungan CSRF saja sudah memusingkan. Seperti enkripsi GPG yang bagus tetapi jarang digunakan, hambatan untuk masuk terlalu tinggi, tetapi imbalannya tampaknya tidak berwujud.

Orang-orang baik dari IETF baru-baru ini menyusun standar untuk membantu developer melindungi diri mereka sendiri dari CSRF dengan sedikit usaha. Ini disebut bendera cookie Situs yang Sama dan sangat mudah diterapkan dan dipahami.

Salah satu alasan untuk masalah dengan cookie dan CSRF adalah bahwa kebijakan asal yang sama (SOP), yang sangat bergantung pada keamanan aplikasi web, belum diperpanjang secara surut untuk mencakup cookie. Dapat dimengerti — ini merusak banyak aplikasi. Tapi itu menyebabkan masalah.

Bendera cookie Situs yang Sama pada dasarnya adalah metode keikutsertaan untuk memperluas SOP ke cookie. Saat Anda menandai cookie, Anda dapat memilih antara dua (saat ini) mode yang memungkinkan — ketat atau lax.

Dalam mode lax, browser menerapkan SOP yang terkait dengan permintaan selain permintaan GET ke cookie. Artinya, jika bendera disetel dan permintaan POST berasal dari asal lain, ia akan menolak untuk mengirim cookie yang ditentukan dari perminataan.

Dalam mode ketat, hal yang sama berlaku seperti dalam mode lax, tetapi meluas ke permintaan GET. Namun, ini dapat menyebabkan masalah. Misalnya, jika Twitter menyetel tanda kuki autentikasi ke mode ketat, tombol praktis yang memungkinkan Anda men-tweet kutipan artikel tidak akan berfungsi.

Ada beberapa hal lain yang perlu diingat saat menggunakan tanda cookie situs yang sama untuk mencegah CSRF:

  1. Menggunakan mode lax berarti aplikasi Anda rentan terhadap berbagai jenis serangan CSRF jika Anda mengizinkannya mengubah status melalui GET. Oleh karena itu, cukup audit root aplikasi Anda untuk memastikan bahwa itu adalah RESTful API tanpa kecuali.
  2. Belum semua browser mendukung ini, dan pengguna mungkin menggunakan browser yang sudah lama tidak mendukungnya. Namun, jika aplikasi Anda belum memiliki perlindungan CSRF, sebagian besar pengguna kini dapat mengaktifkan perlindungan CSRF sebagai lintas situs hanya dalam hitungan menit. Namun, ada baiknya untuk menempatkan implementasi metode sekunder pada peta jalan Anda, terutama jika Anda melihat sejumlah besar browser lawas.

Implementing it is incredibly simple. Here’s a few examples for Express >= v4.14

Simple Example:

res.cookie(‘sessionID’, user.sessionID, { secure: true, sameSite: true });

Dan aplikasi demo fungsional:

/******************************************************************
Express CSRF Protection via Same-Site Demo app. Be sure you have [email protected] and cookie-parser installed first!usage: node ./app.js ${SAME_SITE_FLAG_VAL}Visit localhost:3000 (not 127.0.0.1 - we need two origins) to see the same-site cookie in action.
******************************************************************/var express = require('express');
var cookieParser = require('cookie-parser');
var crypto = require('crypto');
var app = express();
var app_CSRF = express();
app.use(cookieParser());
var sameSite = process.argv[2] || true;app.locals.sessionID = crypto.randomBytes(32).toString('base64');app.get('/', function (req, res) {
    res
    .status(200)
    .cookie('sessionID', app.locals.sessionID, { sameSite: sameSite })
    .send('<html><body>Session Cookie Set!<form method="POST" action="http://localhost:3000/"><input type="submit"\></form></body></html>')
    .end();
});app.post('/', function(req, res) {
 // Yes, this should be a secure time comparison! But it's a demo. Don't do this in your app.
 if(req.cookies.sessionID === app.locals.sessionID){
  res
        .status(200)
        .send('Success! You have sent your POST request from a valid origin, and it passes CSRF checking.<a href="http://127.0.0.1:3001">Test from Cross-Site.</a>')
        .end();
 } else {
  res
        .status(403)
        .send('Fail! Either you do not have a session cookie set, or this POST request came from a different origin and the session cookie was not sent with the request. Access is denied.')
        .end();
 }
});app_CSRF.get('/', function (req, res) {
    res
    .status(200)
    .send('<html><body>Attempt to send request from a separate origin:<form method="POST" action="http://localhost:3000/"><input type="submit"\></form></body></html>')
    .end();
});app_CSRF.listen(3001, function () {
})app.listen(3000, function () {
  console.log('Same-Site CSRF mitigation demo app running on localhost:3000!');
});

selamat mencoba :)