Ataques de Inyección SQL: Qué es y cómo protegerte con PHP

29/11/2024 | MySQL, PHP, Seguridad | 0 comentarios

La seguridad de tu web depende de prevenir inyecciones SQL. Aprende a usar consultas preparadas y validar entradas en PHP.


La inyección SQL (SQL Injection) es una de las vulnerabilidades más comunes y peligrosas en aplicaciones web. Consiste en la manipulación de consultas SQL enviadas a una base de datos, permitiendo a los atacantes acceder a datos confidenciales, y en algunos casos, tomar control total del sistema.

¿Cómo funciona la inyección SQL?

Los ataques de inyección SQL explotan funcionales que no limpian o validan correctamente los datos enviados por el usuario antes de incluirlos en una consulta SQL.

Por ejemplo, para una consulta de login:


<?php
// Consulta vulnerable a inyección SQL
$username = $_POST['username'];
$password = $_POST['password'];

$query = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
$result = mysqli_query($conn, $query);

Si un atacante ingresa como nombre de usuario ' OR 1=1 -- la consulta resultante sería:


SELECT * FROM users WHERE username = '' OR 1=1 --' AND password = ''

El 1=1 siempre es verdadero, el operador -- comenta el resto de la consulta, permitiendo el acceso no autorizado.

Riesgos de la inyección SQL

  • Acceso no autorizado:
    El atacante puede ingresar sin autorización a las plataformas de uso privado.
  • Exposición de datos sensibles:
    El atacante puede acceder a contraseñas, datos personales o financieros.
  • Destrucción de datos:
    Con el acceso a la base de datos, se pueden eliminar toda la data almacenada.
  • Control del servidor:
    En ataques mas especializados, se puede tomar el control del servidor.

Cómo protegerte con PHP

1.- Usar consultas preparadas (Prepared Statements)

Las consultas preparadas separan los datos de la estructura de la consulta, evitando que los datos maliciosos alteren la consulta SQL.

Ejemplo con MySQLi:


<?php
$username = $_POST['username'];
$password = $_POST['password'];

// Usando consultas preparadas con MySQLi
$conn = new mysqli('localhost', 'user', 'password', 'database');

$stmt = $conn->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();

$result = $stmt->get_result();
if ($result->num_rows > 0) {
    echo "Acceso permitido";
} else {
    echo "Acceso denegado";
}

Ejemplo con PDO:


<?php
$username = $_POST['username'];
$password = $_POST['password'];

// Usando consultas preparadas con PDO
$pdo = new PDO('mysql:host=localhost;dbname=database', 'user', 'password');
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username AND password = :password");
$stmt->bindParam(':username', $username );
$stmt->bindParam(':password', $password);
$stmt->execute();

if ($stmt->rowCount() > 0) {
    echo "Acceso permitido";
} else {
    echo "Acceso denegado";
}

2. Validar y sanitizar datos de entrada

Nunca confíes en los datos proporcionados por el usuario. Asegúrate de Validar (Verificar que los datos tengan el formato esperado) y Sanitizar (Eliminar o escapar caracteres peligrosos) los datos antes de usarlos en tus consultas.

Ejemplo:


<?php
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$password = filter_input(INPUT_POST, 'password', FILTER_SANITIZE_STRING);

Para mas información sobre esta técnica puedes leer Cómo filtrar y validar datos en PHP usando filter_var.

3.- Usar ORMs

Los ORMs (Object-Relational Mappers) puede ayudar a evitar ataques de inyección SQL, ya que abstraen la interacción con la base de datos y suelen implementar medidas de seguridad contra estos ataques de forma predeterminada.

Ejemplo con Eloquent (Laravel):



$email = $request->input('email');
$password = $request->input('password');

$user = User::where('email', $email)->first();

if ($user && Hash::check($password, $user->password)) {
    echo "Acceso permitido";
} else {
    echo "Acceso denegado";
}

4. Configurar base de datos

Para evitar accesos no deseados tener un usuario con las siguientes configuraciones:

  • Sólo debe tener acceso a la base de datos de tu aplicación, evitar usuarios compartidos.
  • Para una aplicación de consultar datos, solo permiso SELECT.
  • Para una aplicación que inserta datos, permisos: SELECT, INSERT y tal vez UPDATE.
  • Evita permisos como DROP, ALTER, GRANT o SUPER.
  • Restringe el acceso por IP o dominio, por ejemplo solo acceso desde 127.0.0.1.

Conclusión

Proteger tu aplicación contra ataques de inyección SQL es una tarea preventiva, para ello puedes usar consultas preparadas, validar los datos de entrada o usar ORMs. Si aplicas estas prácticas mejorarás la seguridad general de tu aplicación.

Referencias

Envíar Comentario

En este sitio los comentarios se publican previa aprobación del equipo de Kodetop. Evita los comentarios ofensivos, obscenos o publicitarios. Si deseas publicar código fuente puedes hacerlo entre las etiquedas <pre></pre>