Seguridad de aplicaciones PHP: top 10 vulnerabilidades para principiantes
PHP sigue siendo uno de los lenguajes más populares para el desarrollo web, pero su flexibilidad a menudo causa graves errores de seguridad. Para un principiante es fácil pasar por alto una vulnerabilidad crítica que puede provocar una fuga de datos o la completa vulneración del servidor. En este artículo analizaremos las 10 vulnerabilidades más comunes de las aplicaciones PHP, mostraremos ejemplos de código peligroso y te enseñaremos a protegerte correctamente. El material está preparado especialmente para desarrolladores principiantes que quieren escribir código seguro desde el primer día.
1. Inyección SQL (SQL Injection)
Esta es la vulnerabilidad más conocida y peligrosa. Ocurre cuando la entrada del usuario se inserta directamente en una consulta SQL sin escape. Un atacante puede obtener acceso a la base de datos, modificar o eliminar datos.
Código peligroso:
<?php$id = $_GET['id'];$query = "SELECT * FROM users WHERE id = $id";$result = mysqli_query($conn, $query);?>Cómo protegerse: Utilice consultas preparadas (prepared statements) con PDO o MySQLi.
<?php$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");$stmt->execute(['id' => $_GET['id']]);?>2. XSS (Cross-Site Scripting)
XSS permite a un atacante inyectar código JavaScript malicioso en una página que se muestra a otros usuarios. Esto puede provocar el robo de cookies de sesión o la redirección a sitios de phishing.
Código peligroso:
<?phpecho "Hola, " . $_GET['name'];?>Cómo protegerse: Siempre escape la salida con htmlspecialchars().
<?phpecho "Hola, " . htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');?>3. CSRF (Cross-Site Request Forgery)
El ataque CSRF obliga a un usuario autenticado a realizar una acción no deseada en el sitio (por ejemplo, cambiar la contraseña o transferir dinero). El ataque ocurre cuando el usuario hace clic en un enlace en un sitio de terceros.
Cómo protegerse: Utilice tokens CSRF para todos los formularios y solicitudes que cambien el estado.
<?phpsession_start();if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32));}?><form method="POST"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <button type="submit">Eliminar cuenta</button></form>4. Manejo inseguro de archivos
Permite a un atacante leer o escribir archivos arbitrarios en el servidor. Por ejemplo, a través de path traversal o la carga de shells PHP.
Código peligroso:
<?phpinclude($_GET['page'] . '.php');?>Cómo protegerse: Nunca utilice la entrada del usuario en rutas de archivos. Utilice listas blancas de valores permitidos.
<?php$allowed_pages = ['home', 'about', 'contact'];$page = $_GET['page'] ?? 'home';if (in_array($page, $allowed_pages)) { include($page . '.php');} else { include('404.php');}?>5. Deficiencias en la autenticación y gestión de sesiones
Contraseñas débiles, falta de protección contra fuerza bruta, fijación de sesión: todo esto abre el camino para la toma de control de cuentas.
Recomendaciones:
- Almacene las contraseñas solo en forma hash mediante
password_hash(). - Utilice HTTPS para todas las páginas con autenticación.
- Regenere el ID de sesión después del inicio de sesión:
session_regenerate_id(true). - Establezca un tiempo de vida de sesión corto.
6. Referencia directa insegura a objetos (IDOR)
ID