Tutorial Menggunakan KnightOwl Dalam Mengamankan API GraphQL Anda
Tidaklah mengherankan bahwa GraphQL terus melonjak popularitasnya sebagai alternatif dari RESTful API tradisional. Bahasa kueri yang diketik dengan kuat sangat kuat, fleksibel, dan sangat memudahkan koordinasi antara ujung depan dan belakang aplikasi web kami. Tetapi kekuatan ini harus dibayar mahal: API yang terlalu terbuka mungkin rentan terhadap serangan oleh mereka yang ingin mengeksploitasi bahasa kueri untuk membanjiri server Anda.
Itulah mengapa kami membuat KnightOwl, rangkaian fungsi middleware open source yang dapat dengan mudah ditambahkan ke server Express GraphQL Anda untuk mengurangi kerentanan API Anda. Selain itu, Anda dapat melihat data tentang kueri ke server Anda yang telah ditolak oleh KnightOwl kapan saja dengan masuk ke knightowl.app. Kami baru saja meluncurkan dalam versi beta, dan kami senang untuk membagikan bagaimana kami dapat membantu membuat API GraphQL Anda lebih aman.
Apa itu GraphQL? Apa itu API?
Jika Anda sudah mengetahui apa itu GraphQL, silakan melompat ke bagian berikutnya. Tetapi jika intro itu terdengar seperti kata-kata yang membingungkan bagi Anda, jangan khawatir, kami memiliki Anda. Pertama, kita semua harus memiliki pemahaman yang sama tentang apa yang kita bicarakan saat kita membicarakan tentang APIs.
Antarmuka Pemrograman Aplikasi, atau API, adalah seperangkat aturan untuk cara berinteraksi dengan aplikasi sehingga merespons dengan cara yang konsisten dan dapat diprediksi. Dalam konteks membangun server untuk aplikasi web, API pada dasarnya adalah aturan yang ditetapkan untuk cara meminta informasi dari atau mengirim informasi ke server itu. Ini mencakup semuanya, mulai dari bagaimana perangkat klien dapat meminta halaman beranda situs web hingga cara mengunggah dan menyimpan data ke akun pengguna.
Secara tradisional, API dibangun dengan arsitektur REST ("REST" di sini adalah singkatan dari Representational State Transfer). Dalam RESTful API, aturan untuk berinteraksi dengan aplikasi terutama bergantung pada metode permintaan dan titik akhir yang menjadi tujuan pengiriman permintaan. Ini berarti bahwa untuk memuat beranda mywebsite.com, API kami mungkin meminta klien untuk mengirimkan permintaan GET ke root endpoint kami (mis., ke 'mywebsite.com/'). Sebaliknya, jika pengguna ingin melihat profil untuk akun mereka, mereka harus mengirimkan permintaan GET ke endpoint yang berbeda (yaitu, ke 'mywebsite.com/profiles'). Jika mereka perlu mengedit profil mereka, mereka mungkin mengirimkan permintaan PUT atau PATCH ke endpoint 'mywebsite.com/profiles', yang berisi pembaruan yang mereka inginkan di badan permintaan.
API berbasis GraphQL, sebaliknya, menggunakan titik akhir tunggal dan mengharapkan semua permintaan masuk melalui metode POST. Apa yang sebenarnya dilakukan server dengan permintaan didasarkan sepenuhnya pada kueri yang masuk ke badan permintaan. Skema yang ditentukan oleh server akan mengharapkan jenis kueri tertentu dan bersiap untuk mengembalikan atau memprosesdata yang diketik serupa.
Singkatnya, RESTful API adalah tentang siapa yang Anda tanyakan, sedangkan GraphQL API adalah tentang apa yang Anda tanyakan.
Jadi apa masalahnya?
GraphQL memungkinkan klien mendapatkan data yang tepat, dan hanya data, yang mereka butuhkan, menghemat pengambilan berlebih sambil menetapkan aturan untuk interaksi antara klien dan server yang menyeimbangkan perilaku yang dapat diprediksi dengan fleksibilitas. Kedengarannya sempurna!
Kami menyukai GraphQL! Tetapi dengan RESTful API, Anda mengetahui dan mengontrol berapa banyak informasi yang mungkin dikembalikan oleh permintaan tertentu, karena permintaan itu sendiri tidak memiliki kemampuan untuk mendikte bentuk permintaan. Namun, di GraphQL, permintaan dapat dibentuk dalam konfigurasi berbeda yang tak terhitung jumlahnya sesuai dengan apa yang ingin diminta klien dari server. Meskipun ini semua baik dan bagus saat permintaan datang dari klien menggunakan UI frontend Anda seperti yang Anda inginkan, API Anda juga terbuka untuk kueri yang ditulis oleh
Misalnya, bayangkan Anda sedang mengembangkan API untuk situs web media sosial menggunakan GraphQL. Saat klien meminta informasi tentang pengguna, Anda dapat menulis skema yang menyelesaikan permintaan tersebut dengan mengembalikan tipe objek Pengguna yang berisi bidang yang telah ditentukan sebelumnya: bidang user_id
, bidang user_name
, bidang user_posts
, dan bidang user_friends
. Tetapi beberapa dari bidang ini sendiri akan menjadi tipe kompleks yang mengembalikan banyak bidangnya sendiri; yaitu bidang user_friend
Anda akan menjadi Daftar yang berisi beberapa objek tipe Pengguna lainnya.
Kualitas berlapis dari sistem query dan resolver GraphQL ini rentan terhadap eksploitasi. Cara GraphQL mencegah pengambilan berlebihan adalah dengan menyerahkannya kepada klien untuk memutuskan bidang objek mana yang ingin mereka dapatkan (jadi jika Anda hanya ingin user_name
pengguna, Anda tidak perlu mengambil user_id>
, user_posts
, atau user_friends
). Tapi ini memotong dua arah. Bagaimana jika klien meminta bidang user_friends
dengan semua subbidangnya, dan kemudian untuk setiap objek Pengguna yang dikembalikan dalam Daftar itu, meminta setiap kemungkinan nilai pengembalian di bidang user_friends
mereka, dan seterusnya, hingga mereka membuat satu permintaan menjalankan ribuan lapisan dalam?
Ini dapat dengan mudah membanjiri server Anda, membuat Anda terkena serangan DOS, atau membuat lebih banyak data tersedia untuk klien daripada yang Anda inginkan.
Apa boleh buat
Untungnya, kami dapat mengurangi risiko paparan berlebih dengan mengontrol API GraphQL kami dengan pembatasan biaya, pembatasan kecepatan, dan pembatasan kedalaman untuk menolak permintaan yang kuerinya dapat membebani server kami.
- >Pembatasan biaya adalah proses penguraian kueri untuk menentukan berapa banyak informasi yang diminta (yaitu, berapa "biaya" untuk memproses dan melayani respons). Permintaan yang terlalu mahal dapat langsung ditolak.
- Pembatasan tarif mengontrol kecepatan di mana klien tertentu dapat mengajukan permintaan, dan menolak permintaan yang datang lebih cepat dari tarif tersebut. Karena tidak semua permintaan sama di GraphQL, fungsi ini bisa mendapatkan keuntungan dengan mengandalkan biaya yang ditetapkan ke kueri oleh cost limiter. Misalnya, pembatas biaya dapat melarang satu kueri melebihi 1000 titik kerumitan, sementara pembatas tarif akan melarang setiap alamat IP meminta lebih dari 5000 titik kerumitan dalam interval 60 detik, memungkinkan dibuatnya permintaan yang lebih kecil dan murah pada frekuensi yang lebih tinggi daripada permintaan yang lebih besar dan mahal.
- Pembatasan kedalaman menilai berbagai jalur bidang bersarang dalam kueri untuk memastikan bahwa tidak ada jalur yang melebihi kedalaman maksimum. Jadi dalam contoh objek pengguna/media sosial kita, itu akan menghentikan permintaan tanpa henti untuk teman dari teman dari teman setelah melebihi tingkat kedalaman tertentu.
Jika Anda telah membangun server Anda dengan Express, Anda dapat menggabungkan perpustakaan middleware KnightOwl untuk menambahkan semua fungsi ini dengan mudah, menjaga keamanan server Anda dan mengurangi paparan API Anda. Selain itu, pemantauan bawaan KnightOwl dengan mudah menyediakan kemampuan pengamatan sehingga Anda dapat tetap waspada terhadap serangan pada API Anda.
Memulai dengan KnightOwl
- Pertama, daftarkan akun di knightowl.app. Catat alamat email dan kata sandi Anda, karena Anda akan menggunakannya untuk menghubungkan fungsi middleware ke aplikasi monitor.
-
Untuk menggunakan KnightOwl, Anda harus menjalankan instance Redis di server Anda. Ini dapat dilakukan dengan mudah menggunakan petunjuk di sini. Setelah terinstal, jalankan saja perintah
redis-server
untuk memulainya. Anda tidak perlu melakukan apa pun dengan Redis setelah dijalankan. -
Di dalam direktori proyek Anda, instal KnightOwl dengan
npm install nightowl
. -
Setelah Anda menginstal semua, konfigurasikan bagaimana Anda ingin KnightOwl membatasi kueri dalam hal biaya, tarif, dan kedalaman, lalu tempatkan fungsi ini ke
/graphql
route handler Anda dengan mengikuti petunjuk di README kami. -
Anda baik untuk pergi! Anda dapat masuk kembali di knightowl.app untuk
melihat data
kueri yang telah ditolak KnightOwl kapan saja.
Apa masalahnya dengan monitor?
Saat mendesain KnightOwl, kami tidak puas hanya dengan menghentikan kueri jahat di jalurnya; kami ingin memastikan Anda selalu tahu persis apa yang terjadi, siapa yang mencoba melampaui batas yang telah Anda tetapkan, data apa yang mereka minta, dan mengapa middleware kami menolak permintaan tersebut. Jika Anda ingin tahu tentang bagaimana bagian-bagian berbeda dari perlindungan ini cocok satu sama lain, Anda dapat melihat diagram ini yang memetakan struktur perangkat lunak kami:
Untuk memberikan pengamatan tentang bagaimana kami melindungi API Anda dan apa yang kami lindungi dari Anda, middleware kami tidak hanya menolak kueri — ini menyimpan data kunci tentang kueri tersebut (sementara di Redis, kemudian membersihkan cache ini secara berkala dan mengirimkan kueri yang tersimpan data ke server kami, di mana kami kemudian menyimpannya dalam database relasional yang sesuai dengan ACID). Dengan masuk ke aplikasi web kami, Anda dapat dengan mudah melihat data terkompilasi tentang apa yang terjadi sejak menginstal KnightOwl ke server Anda, termasuk tren kueri yang ditolak, fungsi middleware mana yang menolak kueri mana, dan log yang menyertakan string kueri spesifik yang ditolak.
Jadi bagaimana sekarang?
Dengan fungsi middleware dan monitor aplikasi web yang bekerja bergandengan tangan, API Anda akan lebih terlindungi dari kueri berbahaya, dan Anda akan mendapat lebih banyak informasi tentang permintaan yang berpotensi membahayakan yang masuk ke server Anda.
Untuk membuat akun, kunjungi beranda kami. Untuk menginstal middleware kami, kunjungi halaman npm kami atau jalankan `npm install knightowl` di dalam direktori proyek Anda.
Jika Anda ingin mengetahui lebih banyak tentang kode kami atau membantu kami menjadikan KnightOwl lebih kuat, Anda dapat memeriksa repo GitHub kami:
- Repo dengan kode untuk perpustakaan middleware kami dapat ditemukan di sini.
- Repo dengan kode untuk aplikasi/monitor web kami dapat ditemukan di sini.
Artikel Terkait Lainnya :
- Wajib Tau Buat Kamu Yang Ingin Belajar Tipe Data Di Dalam Ilmu Statistik
- Simak Dulu Sebelum Memulai Karir Menjadi Seorang Copywriter
- Cara Deploy Aplikasi Di Digital Ocean
- Intip Gaji Software Engineer Di Beberapa Startup Terkenal Di Indonesia
- Ini Dia Bedanya Cloud Hosting Dengan Virtual Private Server