Mi sono guardato intorno ovunque e non riesco a trovare la risposta alla mia domanda.
Sto usando il più recente PHP per scripting lato server e MySQL per il mio database. Il set di caratteri è utf8mb4
se questo fa la differenza.
Fino ad ora, ho utilizzato istruzioni preparate per proteggermi dall'iniezione SQL. Tuttavia, poiché la maggior parte delle mie query viene eseguita una sola volta, il codice è in realtà lento . Quando uso $conn->query()
invece, e $conn->real_escape_string()
per tutte le mie variabili, è più veloce.
Tuttavia, $conn->real_escape_string()
è anche lento perché c'è un andata e ritorno ad ogni chiamata. Ma non capisco perché sia necessario un viaggio di andata e ritorno perché mi sembra che la funzione di escape possa essere programmata in PHP.
Dai documenti, una funzione sarebbe simile a questa:
Characters encoded are NUL (ASCII 0), \n, \r, \, ', ", and Control-Z.
function sanitize($str)
{
str_replace(array('\', "$sql = "UPDATE ipsum SET lorem=$str WHERE id=1337";
", "\n", "\r", "'", '"', "\x1a"), array('\\', '\0', '\n', '\r', "\'", '\"', '\Z'), $str);
}
Supponendo che ho fatto in modo che sia nella giusta codifica e che non sia vuoto.
Questo è stato pubblicato come commento in uno dei documenti. A proposito, str_replace
funziona con Unicode.
Tuttavia, ho pensato a qualcosa che ha un po 'più senso. Guardando la pagina , posso allungare questo lotto ulteriore. Per una dichiarazione come questa:
function sanitize($str)
{
return "'" .str_replace(array("\", "'"), array("\\", "\'"), $str) . "'";
}
Non posso semplicemente farlo (e sto verificando in anticipo per assicurarmi che sia un UTF-8):
function sanitize($str)
{
str_replace(array('\', "$sql = "UPDATE ipsum SET lorem=$str WHERE id=1337";
", "\n", "\r", "'", '"', "\x1a"), array('\\', '\0', '\n', '\r', "\'", '\"', '\Z'), $str);
}
E questo preverrà le iniezioni SQL? Perchè no? Non riesco a pensare a un input per il quale fallirà.
In caso contrario, esiste una migliore funzione PHP che può proteggere meglio dall'iniezione SQL?
Grazie in anticipo! Puoi testare SQL qui .
UPDATE: ha ricevuto le risposte che mi aspettavo. Per chiarire, non ti sto chiedendo di dare la tua classica predica di "dichiarazioni preparate sono la cosa migliore che sia mai fatta o morire". Se lo volessi, chiederei a Yahoo! Risposte e non qui.
Mi piacerebbe sapere perché il mio metodo (il secondo) non è sicuro (o se lo è). Sarebbe anche bello includere una discussione su cosa real_escape_string
o istruzioni preparate effettivamente fanno per disinfettare i dati. Sia MySQL che PHP sono open source e sono sicuro che qualcuno sa cosa sta succedendo quando vengono chiamate queste funzioni.
Semplicemente non capisco perché sia necessario un viaggio di andata e ritorno per disinfettare le corde. Come può un metodo come quello non essere implementato in PHP?
UPDATE 2: Ho iterato attraverso tutti i caratteri unicode (da 0x0000 a 0x1F77F, trovato su Wikipedia) e ho notato che, se real_escape_string()
scappa solo caratteri singoli e non frasi (che secondo i documenti che fa), sotto utf8mb4
charset, i caratteri che cambiano sono:
unicode 0 => %bl0ck_qu0te%
unicode 10 =>\n
unicode 13 =>\r
unicode 26 =>\Z
unicode 34 =>\"
unicode 39 =>\'
unicode 92 =>\
Quindi, anche se è utf8mb4
, non è diverso da quello che dicono i documenti (suppongo perché UTF-8 è standard). Quindi, perché non è implementabile in PHP?
Ecco uno script PHP che combina tutti questi unicode e li disinfetta. Ecco un cookie di Windows .