0

evitar sql injection php mysqli




evitar sql injection php mysqli

evitar sql injection php mysqli Como muchos sabrán uno de los ataques más sencillos y peligrosos que cualquiera puede hacer es un ataque de SQL-Injection, estos ataques consisten en inyectar un query maligno a través de una entrada de usuario. Para explicarlo mejor veamos un ejemplo.

Digamos que al momento de autenticarnos en una aplicación es necesario que esta busque nuestro nombre de usuario y nuestra contraseña en la base de datos con el siguiente query:

1SELECT * FROM User WHERE username = ‘Juan Ejemplo’ AND password = ‘ejemplo’;

Bien el código del servidor tomaría el nombre de usuario y el password y los agregaria en el comando que después se ejecutaría por el motor de bases de datos de preferencia.

Bien, qué pasaría entonces si un usuario malintencionado escribe esto como sus credenciales:

12usuario:  Juan Ejemplopassword: ‘; DELETE FROM User WHERE »=’

Entonces el query resultante para estas credenciales seria:

1SELECT * FROM User WHERE username = ‘Juan Ejemplo’ AND password = »; DELETE FROM User WHERE »=»;

ven como un query se convierte ahora en 2 y ambos se ejecutan para borrar toda la tabla de usuarios?

Entonces es por eso que nunca, debemos concatenar un query y pasarlo directamente para ejecutarlo, no olviden la regla de oro:

Siempre utilizar declaraciones preparadas y queries parametrizados.

La mayoría de frameworks php no presentan este tipo de problemas ya que utilizan estos encantos, pero si no estan usando uno es necesario valerse de algunas herramientas.

Php Data Objects (PDO)

Utilizar objetos de datos de php para realizar los queries es facil y seguro, veamos un ejemplo:

123456789101112131415//nos conectamos a la base de datos con un conneciton string$pdo = new PDO(‘mysql:host=localhost;dbname=testdb;charset=utf8mb4’, ‘usuario’, ‘password’);$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //obtenemos las credenciales del usuario$usuario = $_POST[‘usuario’];$password = $_POST[‘password’]; //preparamos nuestra declaracion$stmt = $pdo->prepare(«SELECT * FROM User WHERE username=? AND password=?»);//ejecutamos el query haciendo que pdo reemplace las variables.$stmt->execute(array($usuario, $password));//obtenemos los resultados$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

MySQLi

123456789101112131415//conectarse$mysqli = new mysqli(‘127.0.0.1’, ‘usuario’, ‘password’, ‘db’); //obtener$username = $_POST[‘username’];$password = $_POST[‘password’]; //preparar $stmt = $mysqli->prepare(‘SELECT * FROM User WHERE username = ? AND password = ?’);$stmt->bind_param(‘s’, $username);$stmt->bind_param(‘s’, $password); //ejecutar y obtener$stmt->execute();$result = $stmt->get_result();

Lo que pasa tras bambalinas en ambos casos es que preparamos las declaraciones de query que luego son parseadas y compiladas por el servidor de bases de datos, los signos de interrogación le dicen donde queremos filtrar (escapar) la declaración y luego nos devuelve un comando listo para ejecutarse. Lo importante aqui es que los valores de los parametros estan combinados con la declaración compilada y no son un SQL string, por lo que es seguro decir que una inyección sql es improbable cuando usamos estas medidas.









comparte con tus amigos

borutousumaki

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *