Se puede inyectar cualquier consulta, ya sea de lectura o escritura, persistente o transitoria. Las inyecciones se pueden realizar finalizando una consulta y ejecutando otra separada (posible con mysqli
), lo que hace que la consulta deseada sea irrelevante.
Cualquier entrada a una consulta desde una fuente externa, ya sea de usuarios o incluso interna, debe considerarse un argumento para la consulta y un parámetro en el contexto de la consulta. Cualquier parámetro en una consulta necesita ser parametrizado. Esto conduce a una consulta parametrizada correctamente a partir de la cual puede crear una declaración preparada y ejecutarla con argumentos. Por ejemplo:
SELECT col1 FROM t1 WHERE col2 = ?
?
es un marcador de posición para un parámetro. Usando mysqli
, puede crear una declaración preparada usando prepare
, vincule una variable (argumento) a un parámetro usando bind_param
y ejecute la consulta con execute
. No tienes que desinfectar el argumento en absoluto (de hecho, es perjudicial hacerlo). mysqli
hace eso por ti. El proceso completo sería:
$stmt = $mysqli->prepare("SELECT col1 FROM t1 WHERE col2 = ?");
$stmt->bind_param("s", $col2_arg);
$stmt->execute();
También hay una distinción importante entre consulta parametrizada y declaración preparada . Esta declaración, mientras está preparada, no está parametrizada y, por lo tanto, es vulnerable a la inyección:
$stmt = $mysqli->prepare("INSERT INTO t1 VALUES ($_POST[user_input])");
Para resumir:
- Todos Las consultas deben parametrizarse correctamente (a menos que no tengan parámetros)
- Todos los argumentos de una consulta deben tratarse de la forma más hostil posible sin importar su origen