Forse non sono molto chiaro riguardo alla stored procedure. Qualcuno può spiegarmi come la stored procedure impedisce l'iniezione SQL con un semplice esempio di MySql.
Forse non sono molto chiaro riguardo alla stored procedure. Qualcuno può spiegarmi come la stored procedure impedisce l'iniezione SQL con un semplice esempio di MySql.
Le stored procedure sono una forma di query parametrizzata. Il problema fondamentale che causa l'iniezione SQL sono i dati trattati come linguaggio di query.
$query = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
In questo esempio, se imposto $password
su foo' OR 'x'='x
, otteniamo questo:
SELECT * FROM users WHERE username = 'blah' AND password = 'foo' OR 'x'='x'
Poiché il carattere 'x' è sempre uguale al carattere 'x', questa query restituirà sempre le righe indipendentemente dal fatto che l'utente / passaggio sia corretto. Il database non può sapere che non l'hai inteso, perché viene assegnato solo una stringa senza contesto.
Per evitare ciò, devi essere in grado di conoscere la differenza tra la query e i dati. Le procedure memorizzate risolvono questo problema scrivendo la query in anticipo, con i marcatori per i parametri, in modo che i dati possano essere passati in seguito. Ad esempio:
SELECT * FROM users WHERE username = ? AND password = ?
Il driver del database invia il nome di questa stored procedure (o, nelle query parametriche standard, solo il testo della query stesso) e un elenco di parametri, come distinte entità separate nel protocollo. Ciò significa che il server di database può analizzare la stringa di query come linguaggio di query in modo sicuro e trattare i parametri esclusivamente come dati, senza alcuna ambiguità.
Ho anche ha scritto più a lungo rispondi un po 'indietro che spiega tutto ciò in modo più dettagliato, se ti è utile.
Le procedure memorizzate non sono immuni all'iniezione SQL . Come spiegato qui:
Finché è possibile creare SQL dinamico all'interno delle stored procedure, sei vulnerabile all'iniezione SQL.
E MySQL a partire dalla 5.0.13 in poi, hanno funzionalità SQL dinamiche:
E quindi vulnerabile all'iniezione SQL.
Nel server SQL , ecco un esempio:
VULNERABLE STORED PROCEDURE USING EXEC STATEMENT.
CREATE PROCEDURE getDescription
@vname VARCHAR(50)
AS
EXEC('SELECT description FROM products WHERE name = '''+@vname+ '''')
RETURN
E un altro esempio:
VULNERABLE STORED PROCEDURE USING DYNAMIC CURSOR.
CREATE PROCEDURE printDescriptions
@vname VARCHAR(100)
AS
DECLARE @vdesc VARCHAR(1000)
DECLARE @vsql VARCHAR(4000)
SET @vsql = 'SELECT description FROM products WHERE name='''+@vname+''''
DECLARE cur CURSOR FOR EXEC @vsql
OPEN cur
FETCH NEXT FROM cur INTO @vdesc
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @vdesc
FETCH NEXT FROM cur INTO @vdesc
END
CLOSE cur
DEALLOCATE cur
RETURN
E in Oracle , ecco gli esempi:
La precedente presentazione di David Litchfield in Blackhat Europe ha qualcosa di più serio, dall'iniezione SQL può portare all'escalation dei privilegi - quindi un normale utente Oracle può essere eseguito come un DBA se le stored procedure sono create da DBA (ad es. tutti gli oggetti di sistema di Oracle).
Un database SQL esegue una dichiarazione in diversi passaggi. All'inizio viene analizzato il test dell'istruzione SQL, dopo di che verrà ottimizzato e compilato. Al termine, il database dispone ora di un software interno in grado di eseguire l'istruzione SQL fornita.
Le stored procedure sono precompilate. In altre parole, il database crea quel pezzo di software interno prima di usarlo. In questo caso, solo il codice di programma viene interpretato senza alcuna influenza dei parametri.
Se si passa un parametro completo dell'istruzione SQL completo al database, esso elabora i passaggi sopra descritti.
Per esempio ...
SELECT * FROM myTable WHERE id=1
o dai qualcosa di simile ...
SELECT * FROM myTable WHERE id=1;DROP TABLE myTable
Normalmente nessuno scriverà una dichiarazione come la seconda nel suo codice di programma, ma se si prendono ad esempio parametri diretti da una richiesta web, è possibile che una dichiarazione come quella risulta.
var sqlString="SELECT * FROM myTable WHERE id=";
sqlString = sqlString+request.getParameter("id");
// database parse, compile and optimize
var result=database.doQuery(sqlString);
Se si utilizzano stored procedure o istruzioni preparate. Il processo di analisi e compilazione è già fatto nel database. Tutta l'interpretazione dipende dal tuo codice di programma. Quando lo chiami, il database inserisce solo i parametri dati nel codice precompilato e ne fornisce i tipi di dati eccepiti.
var sqlString = "call queryMyTable(?)";
// get the precompiled statement from database
var statement = database.createStatement(sqlString);
// inject the parameter
statement.setParameter(1,request.getParameter("id"));
// if 'id' is a number it works fine ...
// but if 'id' is '1;DROP TABLE myTable' you will got a type cast error and the risk of SQL injection is banned
var result = statement.execute();
Le stored procedure e le istruzioni preparate sono in vista della sicurezza uguale.
Un altro modo per pensarci, per essere espliciti e aumentare le risposte già fornite.
SELECT * FROM users WHERE username = 'blah' AND password = 'foo' OR 'x'='x'
Senza la dichiarazione preparata il OR
dopo che "foo" è stato trattato come codice
Ora, con l'istruzione preparata, OR
(e tutto il resto) dopo "pippo" viene trattato come dati
Leggi altre domande sui tag sql-injection mysql attack-prevention