La inyección SQL es una técnica de explotación de seguridad en la cual un atacante puede ejecutar declaraciones SQL arbitrarias en una base de datos a través de una aplicación vulnerable. Esto ocurre cuando una aplicación toma datos ingresados por el usuario y los inserta en una consulta SQL sin la debida validación o escape, permitiendo así que el atacante manipule esa consulta para acceder y modificar datos no autorizados.
Una inyección SQL podría permitir a un atacante realizar diversas acciones maliciosas, tales como recuperar datos confidenciales, modificar o borrar datos, y ejecutar operaciones administrativas sobre la base de datos. Por ejemplo, si una aplicación PHP construye una consulta SQL usando directamente los datos solicitados por el usuario, un atacante podría inyectar código SQL malicioso para engañar a la base de datos y provocar acciones no deseadas.
Ejemplo de vulnerabilidad a inyección SQL en PHP:
```php
$username = $_GET[‘username’];
$password = $_GET[‘password’];
$query = “SELECT * FROM users WHERE username = ‘$username’ AND password = ‘$password’”;
$result = mysqli_query($conn, $query);
?>
```
En este caso, si los parámetros `username` y `password` no están debidamente validados, un atacante podría suministrar un valor como `admin’ OR ‘1’=‘1` para el campo `username`, haciendo que la consulta SQL siempre sea verdadera:
```sql
SELECT * FROM users WHERE username = ‘admin’ OR ‘1’=‘1’ AND password = ‘‘
```
Para prevenir la inyección SQL en PHP, se recomienda seguir varias mejores prácticas:
1. Usar consultas preparadas y declaraciones parametrizadas: Este es el método más seguro para manejar consultas SQL. Las declaraciones preparadas garantizan que los parámetros sean tratados como datos y no como comandos SQL. Para implementar esto en PHP, generalmente se utilizan las extensiones MySQLi o PDO.
Ejemplo usando PDO:
```php
$pdo = new PDO;
$stmt = $pdo->prepare(‘SELECT * FROM users WHERE username = :username AND password = :password’);
$stmt->execute([‘username’ => $username, ‘password’ => $password]);
$results = $stmt->fetchAll();
?>
```
Ejemplo usando MySQLi:
```php
$conn = new mysqli(‘localhost’, ‘root’, ‘password’, ‘testdb’);
$stmt = $conn->prepare(‘SELECT * FROM users WHERE username = ? AND password = ?’);
$stmt->bind_param(‘ss’, $username, $password);
$stmt->execute();
$result = $stmt->get_result();
?>
```
2. Validar y sanitizar las entradas: Asegurarse de que todos los datos ingresados por el usuario sean válidos y seguros antes de usarlos en una consulta SQL. Esto incluye verificar que los datos tengan el tipo y formato esperados.
3. Usar funciones apropiadas para escapar los datos: Si no es posible usar declaraciones preparadas, al menos se debería usar funciones para escapar caracteres especiales. En PHP, `mysqli_real_escape_string()` es una función que ayuda a escapar caracteres especiales en una cadena para su uso en una consulta SQL.
Ejemplo:
```php
$username = mysqli_real_escape_string($conn, $_GET[‘username’]);
$password = mysqli_real_escape_string($conn, $_GET[‘password’]);
$query = “SELECT * FROM users WHERE username = ‘$username’ AND password = ‘$password’”;
$result = mysqli_query($conn, $query);
?>
```
Estas prácticas ayudan a proteger las aplicaciones PHP contra ataques de inyección SQL y contribuyen a la creación de sistemas más seguros.
Fuentes:
1. OWASP Foundation. (n.d.). SQL Injection. Retrieved from https://owasp.org/www-community/attacks/SQL_Injection
2. PHP Manual. (n.d.). PDO. Retrieved from https://www.php.net/manual/en/book.pdo.php
3. PHP Manual. (n.d.). MySQLi. Retrieved from https://www.php.net/manual/en/book.mysqli.php