Pruebas de penetración y seguridad defensiva en PHP

Metodología profesional de pentest web

El análisis de seguridad defensiva en aplicaciones PHP exige partir de una postura de desconfianza sistemática (Zero Trust): toda entrada que llega del cliente o de una API externa se trata como potencialmente maliciosa.

  1. Reconocimiento y mapeo: Identificación de puntos de entrada, parámetros ocultos, versiones de componentes y cabeceras HTTP.
  2. Modelado de amenazas: Detección de vectores de ataque manipulables en variables globales (\$_GET, \$_POST, \$_COOKIE, \$_FILES).
  3. Explotación controlada y mitigación: Validación empírica del fallo y aplicación de parches robustos.

Vulnerabilidades críticas, vectores y mitigación defensiva

1. SQL Injection (SQLi)

Ocurre al interpolar o concatenar entradas crudas del usuario directamente en las consultas que ejecuta el motor de base de datos.

  • Código vulnerable: \$db->query("SELECT * FROM users WHERE id = " . \$_GET['id']);
  • Mitigación con PDO y consultas parametrizadas:
\$stmt = \$pdo->prepare('SELECT * FROM users WHERE id = ?');
\$stmt->execute([\$_GET['id']]);
\$usuario = \$stmt->fetch();

2. Cross-Site Scripting (XSS)

Inyección de scripts maliciosos del lado del cliente en páginas que otros usuarios ven.

  • Mitigación: Codificar los caracteres especiales antes de renderizarlos en HTML con htmlspecialchars(\$_GET['input'], ENT_QUOTES, 'UTF-8'); y aplicar políticas CSP (Content Security Policy).

3. Remote Code Execution (RCE) y Command Injection

Uso inseguro de funciones de ejecución del sistema operativo como eval(), system(), exec(), passthru() o shell_exec() con parámetros sin sanear.

4. Local File Inclusion (LFI) y Path Traversal

Inclusión dinámica de archivos locales mediante funciones como include() o require() manipulando secuencias de escape de directorio (../).

  • Mitigación con lista blanca estricta:
\$vistasPermitidas = ['inicio' => 'home.php', 'contacto' => 'contact.php'];
\$destino = \$_GET['seccion'] ?? 'inicio';
\$archivo = \$vistasPermitidas[\$destino] ?? '404.php';
include(__DIR__ . '/views/' . \$archivo);

Preguntas clave

  1. ¿Por qué el uso de funciones de deserialización (unserialize()) con datos controlados por el usuario representa un vector crítico de ejecución de código mediante gadget chains?
  2. ¿Qué atributos de seguridad indispensables deben configurarse en las cookies de sesión (session.cookie_httponly, session.cookie_secure) para prevenir ataques de secuestro de sesión (Session Hijacking)?

© Arturo Juárez Monroy