Quale approccio utilizzare per evitare richieste multiple all'API esposte al pubblico

5

Ho una API in cui il visitatore può inviare una email tramite l'abbonamento:

/ api / subscribe

Per evitare un carico eccessivo dovuto all'esposizione pubblica, come posso proteggere questo endpoint? Devo usare il database o posso farlo senza quello con qualche tipo di memorizzazione nella cache, inmemory etc che rilascia mai 10 minuti, ecc?

    
posta Amel Salibasic 21.07.2017 - 18:29
fonte

5 risposte

2

Ho terminato di utilizzare WebApiThrottle che puoi utilizzare per limitare l'importo della richiesta sull'endpoint selezionato.

    
risposta data 24.07.2017 - 16:00
fonte
4

Ho fatto questo, quindi so come è fatto in modo ottimale. L'idea è di utilizzare una funzione di hash come SipHash per calcolare un valore hash per l'indirizzo IP. Quindi utilizzi un algoritmo token bucket per ciascun bucket hash: ad es. 100 gettoni iniziali in ciascun secchio hash, aggiungi 10 token al secondo fino a un massimo di 100 token e rimuovi un token ogni volta che ricevi una richiesta, altrimenti, se non ci sono token, rifiuta la richiesta. Ciò consentirebbe 10 richieste al secondo con una dimensione massima di burst di 100.

In teoria, è possibile che due hash degli indirizzi IP siano sullo stesso bucket, ma in questo caso d'uso non è un problema, se hai abbastanza bucket hash.

Per quanto riguarda l'aggiornamento dei bucket, puoi eseguirli utilizzando i timer batch. Per esempio. per i bucket 131072, è possibile aggiornare ad es. 4096 secchi per ogni timer e quindi hanno 32 timer che scadono in modo uniforme in un secondo. Quindi, a 1/32 secondi, aggiorni i primi 4096 bucket, a 2/32 secondi, aggiorni i successivi 4096 bucket, ecc. La struttura dati per il mantenimento dei timer è in modo ottimale a coda priorità come un heap binario .

Se implementato in questo modo, se qualcuno inonda il tuo sistema da numerosi indirizzi IP di origine contraffatti, la tua memoria non viene riempita.

La memoria utilizzata da questo approccio utilizza 8, 16 o 32 bit per ciascun hash bucket se si utilizza un array intero. La dimensione intera deriva dalle tue esigenze: ad es. 8 bit non supportano più delle dimensioni burst di 255. Analogamente, 16 bit consentono dimensioni di burst di massimo 65535. Pertanto, ad es. 8 bit o 1 byte per bucket e 131072 bucket impiegano 128 kilobyte di memoria. In nessun posto vicino a essere un problema. Una buona macchina ha almeno 2 GB di memoria, il che significa oltre 15.000 volte la quantità richiesta per questo sistema.

È necessario considerare anche la larghezza di banda della memoria: se ogni bucket viene aggiornato una volta al secondo, la larghezza di banda richiesta è 128 KB / s. I computer di qualità supportano oltre 5 GB / s di larghezza di banda in lettura e scrittura o oltre 40.000 volte ciò che questa mia proposta utilizza.

Salva la cache nella RAM. Non utilizzare un database o un file su disco per questo. Se il sistema si arresta in modo anomalo, allora basta inizializzare tutti i bucket sul valore iniziale.

    
risposta data 21.07.2017 - 19:00
fonte
3

Puoi utilizzare Prova di lavoro per applicare la limitazione della velocità senza dover ricordare gli indirizzi IP.

Con Proof of Work, è necessario che il client esegua una funzione computazionalmente costosa per generare una prova che è possibile verificare a basso costo. Uno dei più comuni PoW è l'inversione hash parziale, in cui è necessario che ogni sottomissione API sia associata a una richiesta hash di prova +, per cui l'hash deve avere un prefisso predefinito (in genere zeri) di una certa lunghezza. Per il cliente, il calcolo della prova richiede di testare centinaia o migliaia di prove potenziali, finché non incappano in uno che ha il numero di zeri richiesto; l'obiettivo dovrebbe essere quello di richiedere ai client tipici di impiegare diversi secondi o minuti di potenza di calcolo per ciascun messaggio inviato. Ma per il server, verificare la dimostrazione implica solo un calcolo hash. Questa asimmetria significa che è molto più costoso per il client generare una richiesta valida, che per il server rifiutare quelle non valide.

Per impedire l'attacco di riproduzione, puoi richiedere che le richieste contengano un timestamp o un contatore. Il tuo server può controllare di rifiutare richieste contenenti timestamp che sono troppo vecchie o che contengono un valore di contatore che era già stato utilizzato.

    
risposta data 21.07.2017 - 20:06
fonte
2

Con esposizione pubblica , intendi che l'API stessa non richiede alcuna autenticazione? Puoi riconsiderare la scelta di renderlo pubblico in primo luogo. Tutto ciò che costa risorse e inoltre potrebbe metterti nei guai (inviare troppe e-mail vorrebbe metterti nei guai con entrambi i filtri spam e le persone che ricevono quelle e-mail) non dovrebbe essere pubblicamente disponibile, ma limitato agli utenti registrati che sei in grado di vietare (o, meglio, rendere ogni richiesta pagata).

Se, per qualche motivo, non è possibile richiedere l'autenticazione, sfortunatamente non c'è molto che tu possa fare. Puoi cercare gli attacchi DOS e DDOS ; troverai molte risorse, ma nessuna ti assicurerà con certezza che l'API verrà utilizzata da persone saggi solo per scopi legittimi .

Per quanto riguarda il blocco per IP, questa è la protezione più basilare, meno efficace e anche la più problematica contro DOS e DDOS. I suoi maggiori problemi sono:

  • Il fatto che lo stesso indirizzo IP possa essere utilizzato da più persone. Nell'azienda in cui lavoro, probabilmente ne sono diverse migliaia che condividono lo stesso indirizzo IP pubblico (o una piccola gamma di indirizzi IP).

    Ciò ha causato alcuni problemi con alcuni siti Web, tra cui Stack Exchange, che ha affermato più volte di aver ricevuto troppe richieste dall'indirizzo IP e ci ha bloccato. Beh, in effetti, centinaia di sviluppatori che lavorano contemporaneamente stanno generando un sacco di richieste.

    In una società precedente, è la Ricerca Google che a volte ci ha bloccato, richiedendo il riempimento di un CAPTCHA. Anche qui, centinaia di persone che lavorano contemporaneamente possono fare molte ricerche su Google ogni minuto.

  • Il fatto che un attacco DDOS sia specificamente eseguito da più indirizzi IP. Potresti ricevere centinaia o migliaia di richieste provenienti da un indirizzo IP diverso, tutte arrivate ai tuoi server nello stesso momento. E anche se provi a bloccare quegli indirizzi (che potrebbero appartenere a persone che non avevano intenzione né abilità di fare del male al tuo server e che non sanno nemmeno che il tuo sito web esiste), l'attaccante può passare relativamente facilmente ad altre macchine.

risposta data 21.07.2017 - 19:03
fonte
-2

Sto usando AWS, gateway API specifico per esporre la mia API, il gateway API consente di migliorare il limite di frequenza (che chiamano quota), quindi gli utenti non possono fare x req / seg. Per me era il modo più semplice per farlo. link

    
risposta data 30.09.2017 - 20:11
fonte

Leggi altre domande sui tag