Denial of Service per query SQL: le query selettive sono migliori delle query che restituiscono molto?

1

Diciamo che ho un modulo di ricerca per un blog (o qualsiasi altro sistema che userebbe SQL per eseguire le query) e voglio proteggerlo dalla negazione del servizio. Un utente malintenzionato vuole attaccare il mio sito invadendo la funzione di ricerca, il che causerebbe un sacco di query SQL e potrebbe comportare il rifiuto.

Questo è teorico quindi non si tratta di un singolo tipo di linguaggio o di un sistema di gestione del database, ma se vuoi puoi immaginare che sia PHP e MySQL (anche se mi chiedo degli effetti in generale piuttosto che specifici per una piattaforma) .

Una richiesta come GET /search.php?s=[SEARCH] ricerca nel database tutti gli articoli contenenti [SEARCH] e li restituisce. Supponiamo che la lunghezza massima del carattere per [SEARCH] sia 128.

Mi chiedo in termini di "perdita di prestazioni" che sarebbe la peggiore forma di attacco tra questi due scenari:

  1. L'utente malintenzionato cerca una stringa casuale di 128 caratteri (ad esempio aisoizeuf[...]deuedujed ).
  2. L'utente malintenzionato cerca ogni volta un singolo personaggio (ad esempio e ).

All'inizio pensavo che l'attacco n. 1 sarebbe stato più efficace, legittimando così un limite rigoroso alla lunghezza del carattere della query di ricerca. Ma poi ho pensato, poiché nel mio esempio stiamo parlando di un blog, che più ricerche su un singolo personaggio potrebbero restituire molti più articoli perché quasi tutto ciò che scrivi conterrà almeno una vocale. Allora ho capito che forse non è una risposta così chiara.

L'attacco n. 1 richiederà più risorse per inviare la query e scansionare tutte le voci nel database, ma non restituirà nulla, mentre l'attacco n. 2 farà l'opposto - non impiegherà molte risorse per analizzare il database ma poiché quasi ogni voce conterrà un'occorrenza della query di ricerca, restituirà quasi ogni voce nel database

Quale attacco ritieni sia più pericoloso e userai più risorse?

    
posta Sewer 27.04.2016 - 18:33
fonte

3 risposte

2

È possibile attenuare entrambi questi problemi creando un indice FULLTEXT. In altre parole, invece di fare in modo che il sistema di database legga l'intera tabella ed esegua la scansione di ogni carattere in ogni campo, il sistema crea un indice che può essere rapidamente ricercato eliminando parole / lettere comuni. L'utente malintenzionato può cercare "e" il più velocemente possibile e l'indice risponderà senza risultati restituiti nel giro di una frazione molto piccola di secondo (e con la memorizzazione nella cache appropriata, le ricerche future costeranno ancora meno). Questo può ridurre la quantità di ricerche necessarie da milioni di byte a poche centinaia di byte, operazione banale per un computer.

La maggior parte degli indici FULLTEXT tendono a utilizzare un'implementazione "b-tree" (o, binary tree). Ciò significa che anche se il tuo attaccante invia 128 caratteri casuali, al contrario di un solo carattere, il database deve solo andare fino a quando non può dimostrare che non ci sono valori corrispondenti, il che significa che non cercherà tutti i 128 caratteri, supponendo che stiamo parlando sui valori casuali reali. La ricerca più esauriente che l'utente malintenzionato potrebbe eseguire sarebbe in realtà utilizzare parole reali da un dizionario che si trovano anche nel tuo blog. Puoi anche limitare le ricerche ad una lunghezza minima scartando parole inferiori, ad esempio, a tre caratteri. Ciò renderebbe il tuo indice più efficace e ridurrebbe le capacità di inviare spam a piccole ricerche.

Per quanto riguarda "pericoloso", è improbabile che entrambi gli attacchi costino molto in termini di costi, supponendo che si tratti di un blog personale: l'intero database può stare nella memoria e quindi non contribuirebbe molto al carico del server anche se venisse colpito centinaia di volte al secondo. È più probabile che si verifichi un DDoS semplicemente perché il sistema operativo del tuo server non può gestire altre connessioni in sospeso anziché la limitazione del database stesso. La maggior parte dei database può gestire centinaia di semplici query di indice al secondo, anche su un computer di casa.

    
risposta data 27.04.2016 - 19:02
fonte
1

Dopo che il sito di un cliente è diminuito a causa di questo problema esatto, abbiamo introdotto una soluzione un po 'semplicistica che ha contribuito a ridurre drasticamente l'effetto di tali attacchi. Come ha detto phyrfox nella sua risposta, un indice FULLTEXT è uno strumento molto efficace sia per le prestazioni che per il contatore DoS.

Dato che stavamo già monitorando i visitatori per le informazioni statistiche, abbiamo fatto un ulteriore passo avanti e abbiamo iniziato a monitorare il loro comportamento nei moduli. Ogni utente ha ricevuto una colonna minuscola nelle sue statistiche che ha tracciato quante volte hanno inviato un modulo (o ha compilato un modulo nel caso di richieste Ajax, ma è stato registrato solo negli utenti.) Quando il totale dell'utente ha raggiunto 32 ( un quarto del valore massimo di un minuscolo) tutte le richieste di utilizzo del modulo sono state ritardate di un secondo. Quando il totale ha raggiunto 48, due secondi, 64, tre secondi, ecc. Al punto di raggiungere 128, l'utente è stato quindi escluso da qualsiasi tentativo di utilizzare i moduli ma non è stato informato di questo . La probabilità che un utente malintenzionato modifichi costantemente gli indirizzi IP è piuttosto bassa in un così breve periodo di tempo e presumerà che il rallentamento sia dovuto al successo del loro attacco DoS e non alla strategia DoS contraria. Il metodo funziona in modo abbastanza simile a come funziona l'algoritmo di bcrypt per le password. Più qualcuno prova a processarlo, più lentamente diventa. Piuttosto che elaborare query SQL a 128, sono state fornite "Nessun risultato trovato" o pagine di risultati memorizzate nella cache. Dal loro punto di vista, stanno ancora implementando un attacco ma dietro le quinte stanno solo facendo un'altra richiesta HTTP. Ovviamente è possibile estenderlo ulteriormente e vietare loro l'accesso in qualche modo, ma ricorda che vietare completamente l'uso è inutile se sono decisi a fare il DoSing: cambieranno il loro proxy e torneranno. Questo è il motivo per cui tutti i nostri sforzi per ridurre l'efficienza dell'attacco erano invisibili.

Il vero vantaggio di questo approccio è la quantità di costi generali che produce. Nel grande schema di un grande sito Web che riceve molti visitatori di spam, un minuscolo extra per utente non contribuirà ad alcun guadagno sostanziale sul database. Questo, combinato con un indice FULLTEXT, dovrebbe impedire alla maggior parte degli attacchi DoS di fare seri danni senza un grande sforzo da parte tua.

    
risposta data 27.04.2016 - 19:16
fonte
0

Ci sono alcune cose che vengono in mente riguardo alla DoS attraverso ciò che hai descritto. Il primo è basato sulla rete, il secondo è basato su query (qual è il limite massimo). Il primo basato sulla rete: questo dipenderà dal design o dalla rete. Ad esempio, c'è un bilanciamento del carico configurato da qualche parte, hai più provider, hai un filtro in atto, ad es. se la query supera N, allora blocca il trasgressore. Il secondo è ciò di cui sembri essere più preoccupato.

Cose da considerare:

  1. Sistema - ha memoria sufficiente per elaborare enormi volumi di query
  2. Configurazione - qual è la query massima impostata su (MySQL, Apache / etc)
  3. Filtro : esiste un filtro per bloccare i criminali
  4. Buffer / Quotas - se imposti una lunghezza massima di 10 caratteri, cosa stai facendo se qualcuno supera questo limite.

1) Il sistema dovrebbe essere progettato correttamente per garantire che ciò non si verifichi. Il tuo progetto dovrebbe includere buffer per N quantità di elaborazione, query, connessioni.

2) La maggior parte delle congetture consente di impostare un limite hardcoded sulla quantità di connessioni che si verificano.

3) Il filtro (specialmente con mod_ratelimit, ecc.) può garantire che ciò non si verifichi.

4) Buffer / quote. Come # 3

Quindi qual è il tuo obiettivo finale? Un DoS tradizionale ti sommergerà perché non eri preparato. In un servizio DoS basato su rete non è possibile fare molto per impedire a 40 Gbps di colpire il sistema 1 Gbps senza l'aiuto di terzi (server cloud, memorizzazione nella cache (Akamai) e così via). Dal punto di vista del sistema / processo, ci sono molti modi per mitigare questo. Quale sarebbe il tuo endgame qui?

    
risposta data 27.04.2016 - 19:01
fonte

Leggi altre domande sui tag