Melakukan dogfood pada API terbatas tarif kami sendiri

117

Gambaran:

Perusahaan saya telah mengembangkan API dengan tarif terbatas. Tujuan kami ada dua:

  • J: Ciptakan ekosistem pengembang yang kuat di sekitar produk kami.
  • B: Mendemonstrasikan kekuatan API kami dengan menggunakannya untuk menjalankan aplikasi kami sendiri.

Klarifikasi: Mengapa rate-limit sama sekali?

Kami menilai batas API kami, karena kami menjualnya sebagai tambahan untuk produk kami. Akses anonim ke API kami memiliki ambang yang sangat rendah untuk panggilan API per jam, sedangkan pelanggan berbayar kami diizinkan lebih dari 1000 panggilan per jam atau lebih.

Masalah:

API terbatas tarif kami sangat bagus untuk ekosistem pengembang, tetapi agar kami dapat melakukan dogfood, kami tidak dapat mengizinkannya dibatasi ke pembatasan tarif yang sama. Bagian depan API kami adalah semua JavaScript, membuat panggilan Ajax langsung ke API.

Jadi pertanyaannya adalah:

Bagaimana Anda mengamankan api sehingga pembatasan kecepatan dapat dihapus di mana dalam proses menghapus pembatasan kecepatan tidak dapat dengan mudah dipalsukan?

Solusi yang Dijelajahi (dan mengapa tidak berhasil)

  1. Verifikasi perujuk terhadap header host. - Cacat karena perujuk mudah dipalsukan.

  2. Gunakan HMAC untuk membuat tanda tangan berdasarkan permintaan dan rahasia bersama, lalu verifikasi permintaan di server. - Cacat karena rahasia dan algoritme akan mudah ditentukan dengan melihat ke JavaScript front end.

  3. Proksi permintaan dan tanda tangani permintaan di proxy - Masih cacat, karena proxy itu sendiri mengekspos API.

Pertanyaan:

Saya mencari pemikiran brilian di Stack Overflow untuk menyajikan solusi alternatif. Bagaimana Anda mengatasi masalah ini?

Jason Waldrip
sumber
13
Tidak boleh. Jika penggunaan Anda sendiri atas API yang tidak ingin Anda batasi pada tingkat pembatasan hanya berasal dari halaman web publik, maka Anda tidak dapat melakukan sesuatu yang aman dari halaman web publik tersebut karena, seperti yang Anda ketahui, ada tidak ada rahasia di halaman web publik. Jadi, apa yang dapat Anda lakukan di halaman web Anda, begitu juga orang lain.
jfriend00
28
Apakah Anda yakin benar-benar memiliki masalah pembatasan kecepatan untuk diselesaikan dalam penggunaan dogfood Anda? Setiap pengguna yang menggunakan situs Anda dan halaman web Anda akan tampak seperti pengguna yang sama sekali berbeda dengan kode pembatas tarif Anda. Jadi, pastikan saja setiap halaman web sesuai dengan aturan pembatasan tarif normal dengan sendirinya dan Anda akan baik-baik saja. Dengan asumsi pembatasan tarif Anda adalah per klien, satu pengguna tidak akan ada hubungannya dengan pengguna lain.
jfriend00
6
Mengapa Anda tidak mempertimbangkan solusi Manajemen API yang memberikan pembatasan kecepatan dan pembatasan pada cakupan per pengguna, per peran / izin atau aplikasi. Misalnya wso2 api palungan
MiddlewareManiac
3
Kemungkinan duplikat dari Rate yang membatasi API dengan pengecualian khusus
spender
28
Dogfood Anda menemukan masalah yang signifikan dengan API publik Anda (yaitu batas kapasitasnya terlalu rendah) dan alih-alih memperbaikinya, Anda mencoba untuk mengatasinya. Mengapa dogfood jika Anda akan mengabaikan masalah yang Anda temukan?
pengguna253751

Jawaban:

93

Karena klien JavaScript Anda mengakses API secara langsung, siapa pun akan dapat melihat apa yang dilakukannya dan menirunya, termasuk menggunakan kunci API yang sama. Anda dapat mencoba membuatnya lebih sulit, seperti dengan mengaburkan kode Anda atau meletakkan berbagai rintangan di jalan, tetapi Anda dan orang yang Anda coba tahan pada dasarnya memiliki akses yang sama. Alih-alih mencoba membuat perbedaan dalam hak istimewa, Anda harus membangun sistem di mana tidak apa-apa bahwa klien tidak resmi menggunakan semua akses dalam cakupannya, tetapi sistem diatur sedemikian rupa sehingga penggunaan resmi di semua klien diatur. lebih besar.

Ini sering dilakukan dengan token akses per pengguna, bukan satu token untuk seluruh aplikasi. Setiap batas token seharusnya cukup untuk penggunaan umum API Anda, tetapi membatasi bagi seseorang yang mencoba menyalahgunakannya. Misalnya, 100 panggilan per menit mungkin lebih dari cukup untuk mendukung penjelajahan biasa, tetapi jika saya ingin membatalkannya, saya tidak dapat melakukannya secara efektif dengan anggaran itu.

Akan selalu ada perlombaan senjata - saya bisa menyiasati batas dengan membuat banyak akun pengguna bot. Itu, bagaimanapun, adalah masalah yang cukup terpecahkan jika Anda hanya menambahkan captcha ke aliran pendaftaran Anda, dengan sedikit biaya bagi manusia yang sebenarnya. Ketika Anda masuk ke dalam skenario ini, semuanya hanyalah pertukaran antara kenyamanan dan pembatasan. Anda tidak akan pernah menemukan sesuatu yang benar-benar antipeluru, jadi fokuslah untuk membuatnya cukup baik dan tunggu sampai seseorang mengeksploitasi Anda untuk mengetahui di mana lubangnya.

Kristján
sumber
8
Menerima ini sebagai jawaban terbaik. Rute yang telah kami putuskan adalah menggunakan token JWT dengan masa kedaluwarsa yang lebih rendah dan untuk meningkatkan batas kecepatan panggilan tersebut. Kami akan mengenkode beberapa informasi tambahan dalam token untuk memberi tahu backend tentang batas tingkat yang lebih tinggi. Karena token ini ditandatangani dengan aman di backend, seharusnya tidak ada masalah dengan spoofing. Seseorang masih dapat menggunakan token tersebut, tetapi token itu akan kedaluwarsa setelah beberapa hari dan karenanya mempertahankan jenis bot apa pun akan lebih sulit dilakukan.
Jason Waldrip
33

Jika hal ini menyebabkan masalah bagi Anda, hal ini akan menyebabkan masalah pada ekosistem diduga pengembang Anda (misalnya, saat mereka mencoba mengembangkan UI alternatif). Jika Anda benar-benar memakan makanan anjing Anda sendiri, buat API (dan pembatasan kecepatan) berfungsi untuk aplikasi Anda. Berikut adalah beberapa saran:

  • Jangan menilai batas berdasarkan alamat IP. Melainkan, batas tarif oleh sesuatu yang terkait dengan pengguna, misalnya ID pengguna mereka. Terapkan batas tarif pada tahap otentikasi.

  • Rancang API Anda sehingga pengguna tidak perlu memanggilnya terus menerus (mis. Memberikan panggilan daftar yang mengembalikan banyak hasil, daripada panggilan berulang yang mengembalikan satu item setiap kali)

  • Rancang aplikasi web Anda dengan batasan yang sama dengan yang Anda harapkan dari ekosistem pengembang Anda, yaitu memastikan Anda dapat merancangnya dalam tingkat pembatasan yang wajar.

  • Pastikan back end Anda dapat diskalakan (lebih disukai secara horizontal) sehingga Anda tidak perlu memaksakan pembatasan pada level yang sangat rendah sehingga menyebabkan masalah pada UI.

  • Pastikan pelambatan Anda memiliki kemampuan untuk mengatasi semburan, serta membatasi penyalahgunaan jangka panjang.

  • Pastikan pembatasan Anda melakukan tindakan yang masuk akal yang disesuaikan dengan penyalahgunaan yang ingin Anda hapus. Misalnya, pertimbangkan untuk mengantri atau menunda pelaku kekerasan ringan daripada menolak koneksi. Sebagian besar ujung depan web hanya akan membuka empat koneksi simultan sekaligus. Jika Anda menunda upaya untuk membuka yang kelima, Anda hanya akan menemukan kasus di mana mereka menggunakan CLI pada saat yang sama dengan klien web (atau dua klien web). Jika Anda menunda panggilan API ke-n tanpa jeda daripada gagal, pengguna akhir akan melihat segalanya melambat daripada rusak. Jika Anda menggabungkan ini dengan hanya mengantri panggilan N API sekaligus, Anda hanya akan menyerang orang yang memparalelkan sejumlah besar panggilan API, yang mungkin bukan perilaku yang Anda inginkan - misalnya 100 panggilan API simultan maka jarak selama satu jam biasanya jauh lebih buruk dari 100 panggilan API berurutan selama satu jam.

Apakah ini tidak menjawab pertanyaan Anda? Nah, jika Anda benar - benar perlu melakukan apa yang Anda minta, rate-limit pada tahap otentikasi dan terapkan batas rate yang berbeda berdasarkan grup yang cocok dengan pengguna Anda. Jika Anda menggunakan satu set kredensial (digunakan oleh tim pengembang dan QA Anda), Anda mendapatkan batas tarif yang lebih tinggi. Tetapi Anda dapat segera melihat mengapa ini pasti akan membawa Anda ke ekosistem Anda melihat masalah yang tidak dilihat oleh tim pengembang dan QA Anda.

abligh
sumber
11

Beli produk Anda. Jadilah pelanggan berbayar Anda sendiri.

"Akses anonim ke API kami memiliki ambang yang sangat rendah untuk panggilan API per jam, sedangkan pelanggan berbayar kami diizinkan lebih dari 1000 panggilan per jam atau lebih."

Ini juga membantu menguji sistem dari perspektif pelanggan.

jkdev
sumber
1
Jawaban yang jelas. Tidak ada kecurangan atau pemalsuan di sini!
wizzwizz4
9

Sayangnya, tidak ada solusi yang tepat untuk ini.

Pendekatan umum biasanya memberikan spoofablecara bagi klien untuk mengidentifikasi diri mereka sendiri (mis. pengenal, versi, dan kunci API - misalnya), bagi klien untuk mendaftarkan informasi tentang diri mereka sendiri yang dapat digunakan untuk membatasi akses (mis. klien adalah server dalam kisaran alamat IP tertentu, jadi hanya izinkan penelepon dalam rentang itu; misalnya klien adalah JavaScript, tetapi dikirim hanya ke kategori browser tertentu, jadi hanya izinkan akses ke permintaan HTTP yang menentukan string agen pengguna tertentu; dll.), lalu menggunakan pembelajaran / pola mesin pengakuan untuk mendeteksi penggunaan yang tidak wajar yang kemungkinan merupakan klien palsu dan kemudian menolak lalu lintas dari klien palsu ini (atau mengonfirmasi dengan klien bahwa penggunaan ini memang tidak berasal dari klien yang sah, ganti kredensial palsu mereka, dan kemudian larang lalu lintas lebih lanjut menggunakan yang lebih lama kredensial palsu).

Anda dapat membuatnya sedikit lebih sulit untuk melakukan spoof dengan menggunakan banyak lapisan kunci. Misalnya, Anda memberikan kredensial yang berumur lebih lama yang berada di server (dan itu hanya dapat digunakan dalam rangkaian terbatas rentang alamat IP) untuk membuat panggilan API yang mencatat informasi tentang klien (misalnya agen pengguna) dan mengembalikan kunci sisi klien yang berumur lebih pendek yang disindikasikan dalam JavaScript untuk digunakan pada klien untuk permintaan API sisi klien. Ini juga tidak sempurna (spoofer dapat mengeluarkan panggilan server yang sama untuk mendapatkan kredensial), tetapi akan lebih sulit jika kunci API yang dikembalikan disertakan dalam JavaScript atau HTML yang dikaburkan (dan sering berubah) (yang akan menyulitkan untuk mengekstrak dengan andal dari respons). Itu juga menyediakan cara untuk mendeteksi spoofing dengan lebih mudah; kunci sisi klien sekarang terikat ke klien tertentu (mis

Michael Aaron Safyan
sumber
8

Dengan asumsi aplikasi yang dipermasalahkan harus terbuka untuk umum, Anda tidak punya banyak pilihan:

Pilih cara lain untuk mendemonstrasikan kekuatan API Anda. Misalnya, tulis aplikasi semacam itu dan bagikan sumbernya, tetapi jangan benar-benar menjalankan kode itu. Pastikan itu didokumentasikan dengan baik, sehingga siapa pun dapat menerapkannya dan melihatnya berfungsi (tunduk pada pembatasan).

Aplikasi yang Anda jalankan perlu difaktorkan ulang untuk menghindari permintaan API sisi klien dan lebih banyak dirender server. Anda masih dapat melakukan dogfood pada API Anda, tetapi tidak dengan cara yang jelas — membuat permintaan yang aman ke API yang bebas hambatan dari sisi server.

Sesuaikan batasan tarif agar aplikasi Anda dapat bekerja dan berinvestasi pada pengoptimalan kinerja untuk menangani beban.

Dan ya, pertama-tama miliki API inti yang bebas throttle, dan simpan di dalam jaringan pribadi. Batasi dalam lapisan terpisah yang dapat diakses publik.

Anton Strogonoff
sumber
4

Dapatkah Anda membuat instance terpisah dari UI dan API bebas hambatan, lalu membatasi akses ke alamat IP yang berasal dari organisasi Anda?

Misalnya, terapkan semuanya di belakang firewall perusahaan Anda, dan lampirkan aplikasi ke database yang sama dengan instance publik jika Anda perlu berbagi data antar instance.

Peter Mortensen
sumber
4

Anda dapat mencoba membuat ID sesi unik, terikat ke alamat IP / pengguna tertentu dan waktu terbatas untuk aktif. Saat pengguna mendownload kode JavaScript frontend aplikasi Anda, masukkan ID sesi yang dihasilkan ke dalam kode sumber JavaScript. ID sesi akan dilampirkan ke setiap permintaan ke API Anda dan batas tarif dicabut.

ID tidak dapat disalin begitu saja untuk spoofing, karena hanya berlaku untuk satu alamat IP, pengguna, dan waktu yang terbatas. Jadi musuh harus memanggil halaman Anda dan memfilter kunci dari sumber JavaScript Anda atau dari mencegat permintaan Ajax setiap kali pengguna baru ingin menggunakannya.

Pilihan lain:

Siapkan proxy untuk aplikasi Anda sendiri dan gunakan obfuscation. Permintaan Ajax ke proxy menggunakan nama yang berbeda dari panggilan API yang sebenarnya dan proxy menerjemahkannya kembali. Jadi aplikasi Anda tidak akan memanggil getDocumentAPI asli Anda, tetapi akan memanggil getFELSUFDSKJEproxy Anda. Proksi akan menerjemahkan panggilan ini kembali ke getDocument dan meneruskannya ke API terbatas tarif yang sebenarnya.

API Anda yang sebenarnya tidak akan membatasi permintaan oleh proxy.

Dan agar orang lain tidak menggunakan proxy Anda untuk aplikasi mereka sendiri, Anda mengubah skema obfuscation setiap hari. Nama panggilan yang dikaburkan dapat dibuat secara otomatis di kode sumber JavaScript Anda dan dikonfigurasi di proxy.

Klien yang ingin menggunakan ini, juga perlu mengikuti perubahan kebingungan Anda untuk menggunakan proxy Anda. Dan Anda masih bisa menggunakan referrer-headers dan sejenisnya untuk logging, jadi Anda bisa menemukan orang yang menggunakan proxy Anda. Atau tangkap mereka saat mengubah skema obfuscation.

Falco
sumber
3
  • Masukkan alamat IP sumber ke daftar putih
  • Gunakan VPN , izinkan anggota VPN
  • Solusi proxy atau addon browser yang menambahkan header HTTP seharusnya baik-baik saja jika Anda dapat mengamankan proxy dan tidak mengkhawatirkan MITM serangan mengendus lalu lintas
  • Solusi apa pun yang melibatkan rahasia dapat mengurangi dampak kebocoran dengan memutar rahasia setiap hari
the8472
sumber
Solusi ini tidak berlaku untuk klien web front end. Sempurna jika mengakses API di backend.
Jason Waldrip
@jason semuanya dapat diterapkan ke frontend
the8472
2

Siapkan beberapa akun, dan pilih salah satunya secara acak di setiap permintaan, atau ubah akun mana yang Anda gunakan setiap jam atau lebih. Dengan cara ini Anda dapat mendistribusikan beban ke nakun, memberi Anda nbatas kali lebih tinggi.

Berhati-hatilah agar tidak menonaktifkan diri Anda secara tidak sengaja jika Anda mencoba menemukan pengguna lain melakukan ini, jika tidak diizinkan untuk pelanggan.

Filip Haglund
sumber