javascript - restful - rest client side




Cibo per cani con la nostra API a tariffa limitata (6)

Panoramica:

La mia azienda ha sviluppato un'API a tariffa limitata. Il nostro obiettivo è duplice:

  • A: Crea un forte ecosistema di sviluppatori attorno al nostro prodotto.
  • B: Dimostrare la potenza della nostra API utilizzandola per guidare la nostra stessa applicazione.

Chiarimento: perché limitare il tasso?

Valutiamo il limite della nostra API, perché la vendiamo come aggiunta al nostro prodotto. L'accesso anonimo alla nostra API ha una soglia molto bassa per le chiamate API all'ora, mentre ai nostri clienti pagati è consentito un massimo di 1000 chiamate all'ora o più.

Il problema:

La nostra API a tariffa ridotta è ottima per l'ecosistema degli sviluppatori, ma per consentirci di mangiare cibo per cani non possiamo permettere che si limiti allo stesso limite di velocità. Il front-end della nostra API è tutto JavaScript, che effettua chiamate Ajax dirette all'API.

Quindi la domanda è:

Come si fa a proteggere un API in modo che il limite di velocità possa essere rimosso laddove nel processo di rimozione di tale limite di velocità non può essere facilmente falsificato?

Soluzioni esplorate (e perché non hanno funzionato)

  1. Verifica il referrer rispetto all'intestazione host. - Difficile perché il referrer è facilmente simulato.

  2. Utilizzare un HMAC per creare una firma basata sulla richiesta e un segreto condiviso, quindi verificare la richiesta sul server. - Difficile perché il segreto e l'algoritmo sarebbero facilmente determinabili guardando nel front-end JavaScript.

  3. Proxy della richiesta e firma la richiesta nel proxy - Ancora imperfetto, poiché il proxy stesso espone l'API.

La domanda:

Sto cercando le menti brillanti su Stack Overflow per presentare soluzioni alternative. Come risolveresti questo problema?


Acquista il tuo prodotto. Diventa un cliente a pagamento di te stesso.

"L'accesso anonimo alla nostra API ha una soglia molto bassa per le chiamate API all'ora, mentre ai nostri clienti pagati è consentito un massimo di 1000 chiamate all'ora o più."

Questo aiuta anche a testare il sistema dal punto di vista del cliente.


Configura più account e scegline uno a caso ad ogni richiesta, oppure modifica quello che usi ogni ora circa. In questo modo è possibile distribuire il carico su n account, offrendo limiti fino a n volte superiori.

Fai attenzione a chiuderti accidentalmente se stai cercando di trovare altri utenti che lo fanno, se non è consentito ai clienti.


Potresti provare a generare un ID sessione univoco, associato a un determinato indirizzo IP / utente e tempo limitato per vivere. Quando un utente scarica il codice JavaScript del frontend dell'applicazione, immette l'ID sessione generato nel codice sorgente JavaScript. L'ID sessione verrà allegato a ogni richiesta all'API e il limite di velocità viene elevato.

L'ID non può essere semplicemente copiato per lo spoofing, poiché è valido solo per un singolo indirizzo IP, utente e periodo di tempo limitato. Quindi un avversario dovrebbe chiamare la tua pagina e filtrare la chiave dalla tua sorgente JavaScript o intercettare la richiesta Ajax ogni volta che un nuovo utente vuole usarla.

Un'altra opzione:

Imposta un proxy per la tua applicazione e usa l'offuscamento. Le richieste Ajax al proxy utilizzano nomi diversi dalle chiamate API reali e il proxy le traduce nuovamente. Quindi la tua applicazione non chiamerebbe getDocument sulla tua vera API, ma chiamerà getFELSUFDSKJE sul tuo proxy. Il proxy tradurrà di nuovo questa chiamata in getDocument e la inoltrerà all'API effettiva a tariffa limitata.

L'API effettiva non limiterà le richieste del proxy.

E così che altre persone non utilizzino il tuo proxy per la propria applicazione, cambi quotidianamente lo schema di offuscamento. I nomi delle chiamate offuscati possono essere generati automaticamente nel codice sorgente JavaScript e configurati nel proxy.

Un client che desidera utilizzare questo, dovrebbe anche tenere il passo con il cambiamento di offuscamento per utilizzare il proxy. E puoi ancora usare le intestazioni dei referrer e simili per la registrazione, così puoi trovare persone che usano il tuo proxy. O catturarli quando si cambia lo schema di offuscamento.


Riesci a creare un'istanza separata dell'interfaccia utente e un'API senza acceleratore e quindi limitare l'accesso agli indirizzi IP provenienti dalla tua organizzazione?

Ad esempio, distribuire tutto dietro il firewall aziendale e collegare l'applicazione allo stesso database dell'istanza rivolta al pubblico se è necessario condividere i dati tra istanze.


Sfortunatamente, non esiste una soluzione perfetta per questo.

L'approccio generale è in genere quello di fornire un modo spoofable ai client di identificarsi (ad esempio un identificatore, una versione e una chiave API - ad esempio), ai clienti di registrare informazioni su se stessi che possono essere utilizzate per limitare l'accesso (ad esempio il client è un server in un determinato intervallo di indirizzi IP, quindi consente solo i chiamanti in tale intervallo; ad esempio, il client è JavaScript, ma consegnato solo a una categoria specifica di browser, quindi consente solo l'accesso alle richieste HTTP che specificano determinate stringhe dell'agente utente; ecc.) e quindi utilizzare l'apprendimento automatico / riconoscimento dei modelli per rilevare un utilizzo anomalo che è probabilmente un client contraffatto e quindi rifiutare il traffico proveniente da questi client contraffatti (o confermare con i client che tali utilizzi non provengono effettivamente dal client legittimo, sostituire le loro credenziali spoofable e quindi non consentire ulteriore traffico utilizzando le credenziali contraffatte precedenti).

Puoi rendere leggermente più difficile lo spoofing usando più livelli di chiave. Ad esempio, si fornisce una credenziale di lunga durata che vive su un server (e che può essere utilizzata solo in un set limitato di intervalli di indirizzi IP) per effettuare una chiamata API che registra informazioni sul client (ad esempio l'agente utente) e restituisce una chiave sul lato client di breve durata che è sindacata in JavaScript per l'uso sul client per richieste API sul lato client. Anche questo è imperfetto (uno spoofer potrebbe inviare la stessa chiamata al server per ottenere le credenziali), ma sarà più difficile se la chiave API restituita è inclusa in JavaScript o HTML offuscati (e che cambiano frequentemente) (il che renderebbe difficile estrarre in modo affidabile dalla risposta). Ciò fornisce anche un modo per rilevare più facilmente lo spoofing; la chiave sul lato client è ora legata a un particolare client (ad es. un agente utente specifico, forse anche un barattolo di cookie specifico) che rende facile da rilevare il riutilizzo in un altro client e la scadenza limita anche la durata in cui la chiave falsificata può essere riutilizzata.


Supponendo che l'app in questione debba essere aperta pubblicamente, non hai molta scelta:

Scegli un altro modo per dimostrare la potenza della tua API. Ad esempio, scrivi una tale app e condividi la sua fonte, ma in realtà non esegui quel codice. Assicurati che sia ben documentato, in modo che chiunque possa distribuirlo e vederlo funzionare (soggetto a limitazione).

L'app da eseguire dovrebbe essere rifattorizzata per evitare richieste API sul lato client ed essere più renderizzata dal server. Puoi ancora dogfood la tua API, ma non in modo ovvio: fai richieste sicure a API libere dal lato server.

Modifica la limitazione della tariffa per consentire all'app di funzionare e investire nell'ottimizzazione delle prestazioni per gestire il carico.

E sì, in primo luogo avere l'API principale senza accelerazione e tenerlo all'interno di una rete privata. Accelerare in un livello separato accessibile al pubblico.





rest