Apache APISIX Meningkatkan Keamanan API dengan Plugin CSRF
API7.ai
February 23, 2022
Poin kunci dari meluncurkan serangan CSRF (cross-site request forgery) adalah membuat server target tidak dapat membedakan apakah sumber dari banyak permintaan adalah pengguna asli atau penyerang. Alur umum serangan adalah pertama-tama penyerang akan memancing pengguna untuk menavigasi ke halaman web yang disediakan oleh penyerang. Halaman ini berisi permintaan yang secara otomatis dikirim ke server target. Halaman kemudian dimuat secara normal dan permintaan secara otomatis dikirim ke server. Bagi server, permintaan tersebut terlihat sama persis dengan permintaan yang biasanya dikirim oleh pengguna, tanpa menyadari bahwa permintaan tersebut dimulai oleh penyerang tanpa sepengetahuan pengguna. Karena permintaan membawa beberapa kredensial pengguna, penyerang dapat mengakses informasi pengguna dengan memparsing kredensial tersebut, sehingga menciptakan risiko keamanan.
Artikel ini memperkenalkan csrf, plugin keamanan CSRF untuk Apache APISIX, dan menjelaskan secara detail bagaimana mengamankan informasi API Anda di Apache APISIX dengan bantuan plugin csrf.
Pengenalan Plugin
Plugin csrf diimplementasikan berdasarkan skema Double Submit Cookie. Seperti yang didefinisikan dalam RFC 7231#section-4.2.1, kami menganggap metode GET, HEAD, dan OPTIONS sebagai metode aman. Menurut konvensi ini, plugin csrf akan membiarkan ketiga metode ini langsung lolos, tetapi akan memeriksa metode lainnya dan menghentikan permintaan yang tidak aman.
Untuk mempertahankan diri dari serangan CSRF, kita perlu membuat token atau pengenal yang tidak dapat dipalsukan dan memastikan bahwa ini tidak dikirim bersama dengan permintaan penyerang. Pengguna perlu membawa token yang diandalkan oleh plugin csrf di header permintaan, dan token dihitung menggunakan kunci untuk penandatanganan. Ini memastikan bahwa token tidak dapat dipalsukan oleh orang lain, sehingga mengamankan API.

Ketika plugin csrf diaktifkan di suatu rute, semua respons permintaan ke rute tersebut akan berisi Cookie yang membawa csrf token.
Pengguna perlu membawa Cookie ini dalam permintaan yang tidak aman untuk rute ini dan menambahkan bidang tambahan di header permintaan untuk membawa konten cookie. Bidang tersebut adalah nilai name dalam konfigurasi plugin sehingga permintaan lolos pemeriksaan plugin CSRF.
Pengguna menyediakan kunci acak dalam konfigurasi plugin, yang digunakan oleh plugin untuk mengenkripsi informasi token dengan hash sha256 dan menghasilkan token CSRF, sehingga memastikan bahwa token tidak dapat dipalsukan.
Cara Menggunakan Plugin
Mengaktifkan Plugin CSRF di Suatu Rute
Buat rute di APISIX menggunakan Admin API dan aktifkan plugin csrf.
curl -i http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "uri": "/hello", "plugins": { "csrf": { "key": "edd1c9f034335f136f87ad84b625c8f1" } }, "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:9001": 1 } } }'
Ada tiga parameter konfigurasi untuk plugin ini.
key: Bidang wajib, nilai dari kunci rahasia acak. Pengguna perlu menyediakan kunci acak.expires: Opsional, waktu kedaluwarsa kunci rahasia acak, nilai default adalah 7200 detik. Karena token CSRF dikirim ke klien menggunakan Cookie, konfigurasi ini ditempatkan dalam konfigurasi Cookie untuk mengontrol waktu kedaluwarsa Cookie. Selain itu, plugin juga akan menghitung waktu untuk menentukan apakah token telah kedaluwarsa.name: Opsional, nama token CSRF, nilai default adalahapisix-csrf-token.
Mengirim Permintaan
Rute pertama kali diakses menggunakan permintaan POST.
curl -i http://127.0.0.1:9080/hello -X POST
Apache APISIX akan menghentikan permintaan dan mengembalikan kesalahan 401. Di header yang dikembalikan, Anda akan menemukan Cookie yang diatur, yang seharusnya adalah nilai default apisix-csrf-token=.... di dalam Cookie jika bidang nama plugin tidak dikonfigurasi. Ini adalah token CSRF yang dihasilkan oleh plugin CSRF. Dalam permintaan, Anda perlu memastikan bahwa permintaan membawa Cookie ini dan bahwa token ditulis di header permintaan.
HTTP/1.1 401 Unauthorized Set-Cookie: apisix-csrf-token= ${apisix-csrf-token};path=/;Expires=Mon, 13-Dec-21 09:33:55 GMT {"error_msg":"no csrf token in headers"}
Contoh penggunaan JavaScript di sisi klien: membaca Cookie menggunakan js-cookie dan mengirim permintaan menggunakan axios.
const token = Cookie.get('apisix-csrf-token'); const instance = axios.create({ headers: {'apisix-csrf-token': token} });
Jika token di Cookie tidak cocok dengan token di header permintaan, permintaan akan dihentikan oleh plugin csrf, seperti yang ditunjukkan dalam contoh berikut.
curl -i http://127.0.0.1:9080/hello -X POST -H 'apisix-csrf-token: ${apisix-csrf-token}' -b 'apisix-csrf-token= ${apisix-csrf-token}'
HTTP/1.1 401 Unauthorized Set-Cookie: apisix-csrf-token= ${apisix-csrf-token};path=/;Expires=Mon, 13-Dec-21 09:33:55 GMT {"error_msg":"csrf token mismatch"}
Terakhir, gunakan curl untuk memverifikasi akses reguler.
curl -i http://127.0.0.1:9080/hello -X POST -H 'apisix-csrf-token: ${apisix-csrf-token}' -b 'apisix-csrf-token= ${apisix-csrf-token}'
HTTP/1.1 200 OK
Secara internal, plugin perlu memverifikasi bahwa token di Cookie cocok dengan token yang dibawa di header permintaan dan menghitung ulang tanda tangan untuk memverifikasi bahwa token valid.
Menonaktifkan Plugin
Hapus informasi konfigurasi yang relevan untuk plugin csrf dan kemudian kirim permintaan untuk memperbarui rute untuk menonaktifkan plugin.
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "uri": "/hello", "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:1980": 1 } } }'
Ringkasan
Artikel ini menjelaskan secara detail bagaimana plugin csrf bekerja dan cara menggunakannya. Kami berharap bahwa artikel ini dapat memberikan pemahaman yang lebih jelas tentang penggunaan plugin untuk menghentikan serangan CSRF di Apache APISIX dan memudahkan penerapannya dalam skenario praktis.
Apache APISIX juga saat ini sedang mengerjakan plugin tambahan untuk mendukung integrasi layanan tambahan, jadi jika Anda tertarik, jangan ragu untuk memulai diskusi di GitHub Discussion, atau melalui mailing list untuk berkomunikasi.