Le connessioni utente DB completate portano a DoS

3

Voglio chiederti chiarimenti e consigli riguardo la seguente situazione emersa durante un test di penetrazione del negozio eCommerce del mio cliente.

Il mio cliente utilizza un software di negozio xt: commerce in combinazione con un MariaDB. Durante una scoperta automatica iniziale di potenziali vulnerabilità SQLi e XSS, il middleware che riportava vari errori (server Web, errori di PHP e database) improvvisamente ha generato più errori che il numero massimo di connessioni utente consentite è stato superato:

(HY000/1203): User xyz already has more than 'max_user_connections' active connections.

Successivamente, sono stati generati messaggi di errore simili:

exception 'Exception' with message 'Unable to connect to database server!'
Error-Nr.: 1045 Access denied for user 'abc'@'localhost' (using password: NO)

In effetti, per i visitatori della pagina non era possibile sfogliare gli articoli o acquistarli poiché nessuno era più in grado di connettersi al database utilizzando l'utente standard.

La domanda era, perché internamente il database manteneva aperte alcune connessioni. Sembrava che alcuni lavori non fossero stati completati. Dopo ulteriori indagini, abbiamo rilevato che il 99% delle connessioni aperte relative a questo particolare utente erano in uno stato simile a uno zombie con stato Waiting for table flush . Immediatamente, pensavo che il client stesse usando uno script di backup non segnalato che avrebbe eseguito una sorta di ANALYZE TABLE come riportato qui , che sfortunatamente collude con il test di penetrazione. E in effetti c'era un lavoro CRON non segnalato che faceva proprio questo. Tuttavia, abbiamo scoperto che questo lavoro non è stato eseguito in questo momento e quindi potrebbe essere impossibile il motivo del comportamento.

Quindi la mia prima domanda è: quale potrebbe essere la ragione che ha portato a questa situazione di deadlock, che potrebbe essere risolta solo con un riavvio del servizio database?

In secondo luogo, durante una seconda fase, che non coinvolgeva affatto i test SQLi ma durante il quale diversi vettori XSS sono stati testati contro uno script potenzialmente vulnerabile in modo automatico, abbiamo visto di nuovo che il numero massimo di connessioni utente era esaurito. Questo è effettivamente un DoS contro il database che lo rende non disponibile per gli utenti legittimi del sito. Abbiamo controllato le voci di configurazione del database correlate e sono state regolate come segue:

max_connections=250
max_user_connections=30

Poiché gli utenti legittimi si connettono tramite PHP utilizzando lo stesso utente DB, sono disponibili 30 connessioni disponibili.

Quindi la mia seconda domanda è: come si possono mitigare attacchi DoS così facili contro il DB, in cui si esaurisce semplicemente la connessione disponibile eseguendo numerose query SQL (vale a dire, si sta ripetutamente interrogando un modulo di ricerca)? Un approccio ingenuo sarebbe impostare max_user_connections=0 . Tuttavia, ci sarà un compromesso e ho un brutto presentimento. Da una parte ci si libera del collo della bottiglia di connessioni limitate. Tuttavia, le risorse del DB saranno sottolineate molto di più. Esiste un modo più intelligente per evitare tale situazione simile a quella di DoS mantenendo allo stesso tempo un uso ragionevole delle risorse del database?

P.S .: Sì, non eseguire mai un test penna attivo / aggressivo su un sistema live. Il cliente ha chiesto esplicitamente (supplicato) di farlo comunque, indipendentemente da quanto gli ho detto che questa è una pessima idea.

    
posta user1192748 06.04.2018 - 09:18
fonte

2 risposte

0

Mi aspetto di dimensionare il tuo sistema di database in modo da poter servire tutte le richieste parallele che il tuo sistema generale dovrebbe consentire. Se ogni richiesta genera una nuova connessione al database (che di per sé può essere vista come una carenza progettuale), 30 sembra molto bassa. Avete effettivamente testato la quantità di overhead di una connessione zombie e quanto tempo occorrerà per chiudere il server di database? Il mio sospetto è che stai combattendo i fantasmi qui, e puoi facilmente utilizzare un numero maggiore di connessioni.

Non conosco la tua applicazione web, ma spesso troverai qualcosa come N service worker che hanno ciascuno una connessione permanente al database (che quindi ha solo bisogno di accettare connessioni N), e questi lavoratori dividono le sessioni utente "abbastanza" tra loro. Non credo che PHP si presti a progetti di servizi di rete così "sane", ma poi di nuovo, mi sono sempre sentito di parte rispetto a PHP.

    
risposta data 06.04.2018 - 16:11
fonte
0

La cosa migliore a cui potrei pensare è di correggere l'applicazione e l'ambiente in cui funzionerà correttamente e di chiudere tutte le connessioni DB dopo l'uso. E se CronJob funziona un po 'di tempo e non chiude Connections, questo potrebbe anche essere un problema.

    
risposta data 06.04.2018 - 10:00
fonte

Leggi altre domande sui tag