Quali sarebbero i potenziali abusi per un'API HTTP che ha accettato l'SQL raw?

9

Mi chiedevo quali potrebbero essere alcuni dei potenziali abusi per un'API HTTP che accettava le query SQL e i set di risultati di output. Il fatto che questa sia la definizione canonica di SQL injection non mi è sfuggita:)

Nel mio caso, ho in mente una specifica applicazione PHP / MySQL che è Magento - una piattaforma di e-commerce.

Ecco alcune misure di sicurezza che ho preso in considerazione:

  • Percorso URL non standard - per impedire la scansione di massa, ogni installazione dovrebbe avere il proprio percorso URL (questo è simile a come viene gestito il back-end di amministrazione di Magento)
  • Un codice API di lunghezza discreta
  • Accesso solo HTTPS
  • Accesso in sola lettura tramite un utente MySQL di sola lettura.
  • Accesso in sola lettura tramite analisi SQL. Richiederebbe un po 'meno di configurazione se l'accesso in sola lettura potesse essere implementato in questo modo. Stavo considerando semplicemente l'analisi delle query per "INSERT", "UPDATE", "DROP", ecc.
  • Tabelle e campi nella lista nera. Per la maggior parte, i dati di configurazione sono memorizzati in una tabella denominata core_config_data , in modo che possa essere inserita nella lista nera. Anche cose come i token della carta di credito possono essere memorizzati in un campo specifico di una tabella specifica. In implementazioni molto povere, anche le carte di credito possono essere archiviate in chiaro, il che ovviamente dovrebbe essere inserito nella lista nera.
  • Tabella delle liste bianche e accesso ai campi - Forse solo consentire l'accesso alle tabelle e ai campi nella whitelist sarebbe un approccio migliore rispetto a una lista nera.
  • Ci sono molte estensioni della community che potrebbero potenzialmente memorizzare anche informazioni sensibili. Sarebbe difficile bloccarli genericamente per impostazione predefinita, quindi penso che una whitelist potrebbe essere l'unica opzione da risolvere per questo.
  • Alcuni meccanismi per un numero massimo / frequenza di tentativi
  • Altre cose standard che vengono utilizzate per proteggere le connessioni SSH, ad esempio una whitelist IP, un'autenticazione a chiave pubblica, VPN, ecc.

Supponendo che queste misure siano state implementate, sarebbe sicuro o più sicuro di, diciamo, l'accesso SSH bloccato da una whitelist IP.

AGGIORNAMENTO: Poche più specifiche dell'applicazione, per dare seguito ad alcune delle domande nelle risposte.

  • La cosa che sto cercando di costruire è un modulo Magento che verrà distribuito nello store e accetterà le query SQL per restituire i dati alla mia app SaaS. Possiedo sia il modulo che l'app SaaS.
  • L'applicazione in questione sarebbe un'app SaaS che si collegava a Magento per inserire i dati. Quindi non è una situazione in cui solo i dipendenti fidati hanno accesso.
  • Il livello minimo di sicurezza ideale (dal punto di vista della quantità di configurazione) sarebbe quello di non utilizzare un utente di sola lettura.
  • Supponiamo che i falsi positivi che potrebbero essere bloccati non siano un problema (scusa, "Bobby Insert Tables").

UPDATE 2: Volevo solo dare un po 'di più alla ragione per cui ho scelto di inquadrare questa domanda in termini di confronto con una connessione SSH con una whitelist di indirizzi IP.

Una connessione SSH a tutti gli effetti è già funzionalmente uguale a un'API SQL raw (più molto di più) nel senso che è possibile connettersi a MySQl e quindi fare qualsiasi cosa. Quindi il mio pensiero è che se un'API SQL è sicura o più sicura di una connessione SSH, può presentare un livello di rischio accettabile.

Inoltre, so che questo tipo di domande può essere eccessivamente soggettivo, quindi ho voluto inquadrarlo in un modo che potesse avere una risposta relativamente obiettiva, motivo per cui volevo confrontarlo con uno specifico scenario SSH.

    
posta kalenjordan 15.05.2014 - 21:29
fonte

3 risposte

9

Il potenziale di abuso dipende ovviamente dall'applicazione. Si rivolge solo a dipendenti fidati su una intranet / VPN con accesso privilegiato? Questi dipendenti avrebbero altrimenti accesso in sola lettura al DB, perché c'è una moltitudine di query diverse che dovranno eseguire sui dati? In tal caso, posso immaginare di consentire la generazione di query SQL raw arbitrarie da parte dell'utente fidato.

Oppure questa applicazione si trova di fronte a qualsiasi attaccante casuale che potrebbe vedere il tuo negozio online e sta cercando di fare il caos? In tal caso, ti consiglio vivamente di non farlo. Prenditi il tempo e passa attraverso i flussi di lavoro e crea le query con parametri consentite che hanno il permesso di essere eseguiti - l'utente dell'API HTTP ha solo il permesso di modificare i parametri di queste query.

L'analisi del comando SQL per cattivi termini come UPDATE / DROP è una pessima idea. Le persone possono ottenere un superamento intelligente di queste misure preventive (ad esempio, ignori i filtri che rimuovono i tag <script> utilizzando <scr<script>ipt> che diventa <script> ). Allo stesso modo potrebbero esserci ragioni valide per alcuni campi per avere il valore "Aggiorna" in esso. Esistono possibilità di problemi di codifica / problemi di normalizzazione Unicode per ignorare il filtro. Ad esempio, un utente malintenzionato invia DRO%C0%50 nella stringa codificata URL che supera il filtro che contrassegna "DROP", ma quando i byte DRO\xc0P vengono inviati al database, il suo elaborato è identico a DROP che consente a un utente malintenzionato di cadere il database. (Per ulteriori informazioni, consulta questo trucco utilizzato in attacchi di attraversamento di directory ).

Avere un account di sola lettura è una soluzione migliore, ma ancora una volta non si può desiderare che un utente malintenzionato sia in grado di accedere ad alcuni campi privati (ad es. CC #s, hash di password, ecc.). Inoltre, non è difficile solo creare comandi SQL dannosi che richiedono molta CPU e possono essere usato per fare un attacco denial of service sul tuo database .

Lasciando un codice di scrittura dell'utente non affidabile (e un comando SQL è un codice) è sempre un anti-modello e dovrebbe essere evitato. Sì, questo richiederà più lavoro inizialmente con le query parametriche consentite, ma ne vale la pena.

EDIT:

Se le query generate dall'applicazione sono sempre completamente affidabili, si tratta di un problema diverso. Questa è la tua applicazione sta generando coppie di query parametrizzate come "SELECT name FROM users WHERE id = ?" inviate al database insieme a un array di input utente non attendibile - ["1"] o in caso di un attacco di SQL injection fallito ["1 OR 1 = 1; DROP TABLE user; --"] ). O potenzialmente più problematico, ma possibilmente sicuro si utilizzano alcune già conosciute funzionalità di sanitizzazione dell'iniezione SQL per sanificare il proprio input per inviare qualcosa. Personalmente non rischierei la seconda via, ma una funzione sanitizzante matura potrebbe essere in grado di farlo.

Quindi tutto ciò che devi fare è utilizzare la crittografia autenticata (ad esempio, i messaggi sono crittografati e MAC'd) tra l'applicazione e l'API HTTPS. Una lista bianca di indirizzi IP sarebbe un modo ragionevole per realizzare questo (oltre a inviare una password) su tutto il TLS (e verificare l'identità dell'altro server che ospita l'API per prevenire gli attacchi di Man in the Middle).

    
risposta data 15.05.2014 - 22:00
fonte
4

La maggior parte dei database (e questo include MySQL) sono progettati per supportare questa modalità operativa in modo sicuro. Questo è stato ampiamente utilizzato con applicazioni "fat client" che accedono direttamente al database. L'idea è di fornire agli utenti rilevanti le autorizzazioni del database di cui hanno bisogno e il database controlla l'accesso. Alcuni database (in particolare Oracle) supportano autorizzazioni estremamente granulari, controllo a livello di riga e colonna, nonché "database privati virtuali".

Oggigiorno, i grossi clienti tendono ad accedere direttamente a un servizio web piuttosto che a un database, ma un modello simile viene utilizzato per il personale analitico che deve eseguire query personalizzate, ma solo con autorizzazioni limitate sul database.

Sfortunatamente, la sicurezza di questo approccio è stata ampiamente screditata. La maggior parte dei database ha avuto numerose vulnerabilità in cui un utente di database con privilegi limitati può aumentare i propri privilegi. In particolare, Oracle ha avuto dozzine di tali vulnerabilità. Al contrario, molti database hanno avuto alcune vulnerabilità che consentono a un utente remoto non autenticato di assumere il controllo del database.

Alcune società di sicurezza (tra cui il mio datore di lavoro ) offrono strumenti e servizi per migliorare la sicurezza del database. Tuttavia, la tendenza dell'architettura è rendere i database più privati e accessibili solo ai server delle applicazioni, il che riduce l'importanza di questo tipo di sicurezza.

Se sei davvero interessato a fare ciò che proponi, la sicurezza del tuo database diventa molto più importante. Il tuo suggerimento di analizzare e filtrare query SQL ha qualche merito, anche se fai attenzione che SQL sia estremamente complesso da analizzare. Esistono appliance (ad es. Firewall di database Oracle) che eseguono questa operazione, sebbene non siano realmente mirate al tuo scenario.

Forse hai bisogno di qualche API di query generica, ma non necessariamente di SQL? In tal caso potresti prendere in considerazione qualcosa come l'API Java Persistence . Questo può essere associato a SQL sul server, ma poiché è più semplice di SQL, c'è meno da sbagliare.

    
risposta data 15.05.2014 - 22:21
fonte
2

Per aggiungere a ciò che altri hanno detto, non hai bisogno dell'accesso in scrittura alla tabella del database per installa backdoor . Sebbene usasse SQL Server piuttosto che MySQL, qualcuno una volta mi ha mostrato uno script che permetteva di creare nuovi utenti sul server tramite SQLI (eseguendo il bombardamento verso il sistema, credo, non ricordo).

Se hai bisogno di un accesso flessibile ai dati, esaminerei un wrapper OData che protegge il database non eseguendo SQL arbitrario, ma abbastanza flessibile da supportare query variabili.

Ho visto comunque applicazioni che inviavano SQL nel loro HTML (credo in facebook), ma lo hanno inviato firmato in modo che non accettassero il back SQL se non provenisse da loro. Significa che nessuno potrebbe cambiarlo senza rompere la firma, sulla quale rifiuterebbero la richiesta.

    
risposta data 15.05.2014 - 22:18
fonte

Leggi altre domande sui tag