Inyección de MySQL y SQL

Si ingresa la entrada del usuario a través de una página web y la inserta en una base de datos MySQL, es probable que se haya dejado abierto debido a un problema de seguridad conocido como inyección SQL… En este capítulo, aprenderá cómo prevenir esto y proteger sus scripts y declaraciones MySQL.

La inyección de SQL generalmente ocurre cuando le pide al usuario una entrada, como su nombre, y en lugar de un nombre, le da una declaración de MySQL que, sin saberlo, ejecuta en su base de datos.

Nunca confíe en los datos proporcionados por el usuario, procese estos datos solo después de la verificación; esto generalmente se hace mediante la coincidencia de patrones. En el siguiente ejemplo, el nombre de usuario está limitado a caracteres alfanuméricos más un guión bajo y tiene entre 8 y 20 caracteres; cambie estas reglas según sea necesario.

if (preg_match("/^w{8,20}$/", $_GET['username'], $matches)) {
   $result = mysql_query("SELECT * FROM users WHERE username = $matches[0]");
} else  {
   echo "username not accepted";
}

Para demostrar este problema, considere el siguiente pasaje.

// supposed input
$name = "Qadir'; DELETE FROM users;";
mysql_query("SELECT * FROM users WHERE name="{$name}"");

La llamada a la función debe recuperar una entrada de la tabla de usuarios donde la columna de nombre coincide con el nombre especificado por el usuario. En circunstancias normales, $ name solo puede contener caracteres alfanuméricos y posiblemente espacios. Pero aquí, agregando una consulta completamente nueva a $ nombre, acceder a la base de datos es un desastre. La solicitud DELETE ingresada elimina todos los registros de los usuarios.

Afortunadamente, si está utilizando MySQL, mysql_query () La función no permite la pila de solicitudes o la ejecución de múltiples solicitudes en una sola llamada de función. Si intenta sumar las solicitudes, la llamada fallará.

Sin embargo, otras extensiones de base de datos PHP como SQLite y PostgreSQL, ejecuta con éxito consultas compuestas, ejecuta todas las consultas en una sola línea y plantea un problema de seguridad grave.

Prevención de la inyección de SQL

Puede manejar todos los caracteres de escape de forma inteligente en lenguajes de secuencias de comandos como PERL y PHP. La extensión PHP MySQL proporciona la función mysql_real_escape_string () para escapar de los caracteres de entrada que son específicos de MySQL.

if (get_magic_quotes_gpc()) {
   $name = stripslashes($name);
}

$name = mysql_real_escape_string($name);
mysql_query("SELECT * FROM users WHERE name="{$name}"");

COMO arreglar

Para resolver el problema LIKE, el mecanismo de escape personalizado debe convertir los caracteres% y _ proporcionados por el usuario en literales. Usar addcslashes (), una función que le permite especificar el rango de caracteres a escapar.

$sub = addcslashes(mysql_real_escape_string("%something_"), "%_");
// $sub == %something_
mysql_query("SELECT * FROM messages WHERE subject LIKE '{$sub}%'");

🚫