Un prof ha detto che l'injection SQL è erroneamente chiamato perché in realtà si verifica dal programma che genera SQL (es. Perl, PHP ecc.) e mi chiedo se SQL sia "abbastanza complesso" da avere qualche vulnerabilità che in realtà è colpa sua?
SQL ha la stessa vulnerabilità di tutti gli altri linguaggi di programmazione dinamicamente interpretati (questo include script di shell, Javascript, PHP ...), che chiamo "data is code". Tali linguaggi hanno una sintassi concreta che è pensata per il consumo umano (" select * from users where
...": parole e segni che il cervello umano afferra). La loro elaborazione comporta un primo passo che viene chiamato analisi : la sequenza di caratteri è suddivisa in una struttura interna che descrive < em> che significa dell'espressione, in un modo che il computer può utilizzare in modo efficiente. L'analisi è un argomento ben noto ma anche se gli algoritmi sono noti da decenni, è ancora relativamente complesso per il programmatore umano.
Quando una lingua viene interpretata dinamicamente, rende seducentemente facile creare l'espressione da parametri ottenuti dinamicamente. Per esempio. "%codice%". Le vulnerabilità di SQL injection ci sono nascoste. Il problema è fondamentale: costruendo l'espressione nella sintassi concreta , il programmatore esegue un'inversione ad hoc del parsing. Per rendere tali cose robuste, il programmatore deve padroneggiare tutti i modi sottili con cui opera l'analisi; deve pensare a ogni angolo oscuro delle specifiche del linguaggio. Molti programmatori la pensano in termini di "devono sfuggire a personaggi pericolosi" e lavorano sul presupposto che i pochi personaggi pericolosi che potrebbero pensare rappresentino effettivamente tutti i "personaggi pericolosi" che potrebbero mai esistere. Ciò lascia la porta aperta a molti problemi, in particolare quando lo sviluppatore del sito Web, il suo framework di programmazione e il database dietro di esso non concordano pienamente su cosa sia un "personaggio pericoloso" e tali problemi sono soggetti a molti motivi, tra cui semplici aggiornamenti del software.
Vedi ad esempio questa domanda per un esempio del genere di cose che non viene catturato dalla struttura mentale "che sfugge al personaggio". Ogni volta che vedo le funzioni select * from users where id = $paramIdFromWebForm;
e mysql_escape_string()
, i miei occhi sanguinano, e mi chiedo se non c'è da qualche parte una funzione chiamata mysql_real_escape_string()
.
Tuttavia, esiste un modo corretto per creare espressioni SQL in modo dinamico senza entrare nei problemi di "dati è codice": espressioni parametrizzate . Si tratta di lavorare con la rappresentazione astratta del codice SQL, l'analisi dopo . Quando usiamo le espressioni parametrizzate, non proviamo a invertire il passo di analisi, e la sicurezza è molto migliorata (ed è buona anche per le prestazioni).
Quindi non è proprio l'errore di SQL ; il programmatore è ancora da incolpare, per non usare le giuste soluzioni che esistono e sono documentate . Potremmo ancora considerare che i progettisti SQL e, in particolare, le persone che hanno integrato SQL in PHP, avrebbero dovuto fare qualche sforzo per rendere l'espressione SQL dinamica un po 'più difficile quando non si utilizza la parametrizzazione. Per una migliore progettazione della lingua (in relazione a questo specifico problema), vedi LINQ : mantiene la sintassi a cui appartiene, vale a dire nel codice sorgente, non nelle stringhe di caratteri interpretate in runtime.
La maggior parte delle volte l'iniezione SQL si verifica perché le persone non la usano correttamente nel loro codice. Se si utilizza SQL nel codice, è necessario utilizzare le istruzioni preparate anziché utilizzare le variabili di aggiunta alla stringa SQL.
SQL è solo uno strumento, se non si utilizza lo strumento in modo corretto si avrà un brutto momento.
Se tieni il coltello per la lama, ti taglierai. Ma non è colpa della lama.
SQL ha la stessa debolezza intrinseca della maggior parte delle lingue: farà esattamente quello che gli dici di fare.
Il problema sorge quando non si pulisce correttamente l'input, o gli utenti del database hanno le autorizzazioni oltre a ciò di cui hanno bisogno, consentendo a terze parti non fidate di dirgli cosa fare. Se gli dicono di fare qualcosa di male ... farà qualcosa di male.
Diverse implementazioni hanno avuto varie vulnerabilità nel corso degli anni, inclusa la recente scoperta che alcune build di MySQL consentono di accedere con qualsiasi password all'incirca 1 su 256 volte: link
Ma l'iniezione SQL è generalmente un difetto nel programma tra l'utente e il database (sito Web PHP, ecc.)
Leggi altre domande sui tag sql-injection