Skip to main content
PHP

Como evitar hackeos de inyección SQL

Por 30 noviembre, 2016Sin comentarios
Evitar hackeos de inyección SQL

Cuando tenemos una página web o una aplicación web se le da mucha importancia a la seguridad del sitio contra hackers mal intencionados que pueden llegar a ser como un grano en partes incómodas. Mas si manejamos bases de datos con información sensible de los clientes o nuestras. Uno de los peligros que podemos encontrarnos es la inyección SQL.

¿Que es la inyección SQL?
Es un método que utilizan los hackers para infiltrar código intruso aprovechando una vulnerabilidad en las consultas SQL. Utilizan entradas de datos como formularios para «colar» código que ejecutan nuevas consultas SQL que nosotros no hemos puesto. Así pueden modificar, descubrir, incluso eliminar campos de la base de datos.
Un ejemplo. Imaginémonos que tenemos un formulario con los campos nombre y email. Primero pasamos los datos por POST, los recogemos con la variable $_POST y luego las insertamos por una consulta SQL a una base de datos:

$nombre = $_POST['nombre'];
$email = $_POST['email'];

$consulta = "INSERT INTO clientes('nombre','email') VALUES('$nombre','$email')";

//Ejecutamos consulta
$query = mysqli_query($conexion,$consulta);

Y si un usuario «amable» pone esto en el campo email:
ejemplo@email.com’); DROP TABLE clientes;
¿Qué sucedería? Que adiós a tu base de datos. Esto es mayormente una inyección SQL. Pero no te preocupes. Aunque parezca tan sencillo hackear una base de datos, existen varios métodos para protegernos contra este peligro. Y de esto trata este post. PHP tiene dos funciones reservadas que nos previenen de la inyección SQL. Podemos utilizar una u otra dependiendo del tipo de enlace que utilicemos con la base de datos (mysqli o PDO). El cometido de estas funciones es entrecomillar la cadena o String que recibamos y escapar caracteres especiales. De esta manera anulamos el peligro de un código malicioso. Una de ellas es mysqli_real_escape_string(). La utilizamos cuando hacemos conexiones mysqli. Por supuesto tenemos otra idéntica para mysql:

//Establecemos conexión con la base de datos
$conexion = mysqli_connect('localhost','username','password','database') or die ("Error: " . mysqli_errno());

$entrada = $_POST['entrada'];

//Creamos consulta
$consulta = "INSERT INTO clientes('entrada',) VALUES('$entrada')";

//Limpiamos cadena
$entrada = mysqli_real_escape_string($conexion,$entrada);

//Ejecutamos consulta
$query = mysqli_query($conexion,$consulta);

Si utilizamos conexiones PDO podemos usar la función PDO::quotes:

$conexion = new PDO("mysql:host=localhost;dbname=miBasedeDatos;...");

$conexion = mysql->quote($entrada);

Supuestamente, estas funciones son más que suficiente para la inyección SQL. Pero encontré hace tiempo 3 funciones muy interesantes que cumplen el mismo propósito y nos sirven para cualquier proyecto. Una es para escapar una cadena de texto y las otras para cadenas numéricas:

function escapeCadena($input){
   $input = str.replace("'", """, $input);
   return $input;
}

Con esta función sustituimos una comillas simple por comillas doble y anulamos el peligro.

function isNaN($var){
   return !preg_match('/^[-]?[0-9]+([\.][0-9]+)?$/', $var);
}

function escapeNumero($cad){
   if(isNaN($cad)){
      return "";
   } else {
      return $cad;
   }
}

Con estas funciones comprobamos si es un número y sino, devuelve vacío. Ahora solo tenemos que llamar estas funciones cuando recojamos las variables POST:

$nombre = escapeCadena($_POST['nombre']);
$telefono = escapeNumero($_POST['tel']);
Jairo Calero

Desarrollador web frontend y backend, especialista en webs app desarrolladas en PHP y Javascript. Experto en HTML, CSS3, PHP y Javascript con frameworks y librerías como jQuery, Angular y Bootstrap. Gestor de herramientas SEO como Google Analytics, Search Console, SEMrush o Hotjar. Email marketing y Big data.

Deja tu respuesta