Qualsiasi query può essere iniettata sia in lettura che in scrittura, persistente o transitoria. Le iniezioni possono essere eseguite terminando una query ed eseguendone una separata (possibile con mysqli
), il che rende irrilevante la query prevista.
Qualsiasi input a una query da un'origine esterna, sia che provenga da utenti o anche interno, dovrebbe essere considerato un argomento per la query e un parametro nel contesto della query. Qualsiasi parametro in una query deve essere parametrizzato. Ciò porta a una query parametrizzata correttamente da cui è possibile creare un'istruzione preparata ed eseguire con argomenti. Ad esempio:
SELECT col1 FROM t1 WHERE col2 = ?
?
è un segnaposto per un parametro. Usando mysqli
, puoi creare una dichiarazione preparata usando prepare
, associa una variabile (argomento) a un parametro usando bind_param
ed esegui la query con execute
. Non devi assolutamente ripulire l'argomento (in effetti è dannoso farlo). mysqli
lo fa per te. Il processo completo sarebbe:
$stmt = $mysqli->prepare("SELECT col1 FROM t1 WHERE col2 = ?");
$stmt->bind_param("s", $col2_arg);
$stmt->execute();
Esiste anche un'importante distinzione tra query parametrizzata e dichiarazione preparata . Questa istruzione, sebbene preparata, non è parametrizzata ed è quindi vulnerabile all'iniezione:
$stmt = $mysqli->prepare("INSERT INTO t1 VALUES ($_POST[user_input])");
Per riassumere:
- Tutti Le query devono essere parametrizzate correttamente (a meno che non abbiano parametri)
- Tutti gli argomenti di una query dovrebbero essere trattati nel modo più ostile possibile, indipendentemente dalla loro origine