Seguridad PHP explicada · defensivo
Inyección de objetos PHP: qué es y cómo corregirla
Pasar datos controlados por el usuario a unserialize() permite al atacante elegir qué objetos crea PHP. El manual de PHP advierte justamente contra eso.
Última actualización
Qué es
Al deserializar una cadena, PHP recrea los objetos descritos y puede llamar a métodos mágicos como __wakeup() y __destruct(). Si la cadena viene de una cookie, un formulario o una petición API, el atacante puede elegir clases ya cargadas por la aplicación o sus bibliotecas y encadenar sus métodos hasta escribir archivos o ejecutar código. MITRE la clasifica como CWE-502.
Cómo detectarlo
- Busque
unserialize(en su código y rastree el origen de cada argumento. Cualquier camino desde$_GET,$_POST,$_COOKIE, cabeceras, archivos subidos o campos de base de datos que los usuarios puedan escribir es un hallazgo. - Revise igual los plugins de terceros y bibliotecas antiguas; muchos avisos históricos de plugins de CMS fueron inyección de objetos.
- El análisis estático con reglas de seguridad (PHPStan, Psalm) y la auditoría de dependencias (
composer audit) detectan paquetes vulnerables conocidos.
Cómo corregirlo
- Use
json_encode()yjson_decode()para datos que cruzan un límite de confianza; JSON no puede crear objetos PHP. - Si
unserialize()es inevitable, pase['allowed_classes' => false]o una lista explícita corta. Aun así, el manual de PHP desaconseja entradas no confiables. - Firme con HMAC los datos serializados que guarde en el cliente y verifique la firma antes de decodificar.
- Mantenga frameworks y bibliotecas actualizados para eliminar cadenas de gadgets conocidas.
Comprobaciones de solo lectura y patrones seguros
# Find unserialize() calls that may receive request data (read-only)
grep -rnE "unserialize\s*\(" --include=*.php . | grep -vE "/vendor/|/tests?/"
// Safer: exchange data as JSON
$data = json_decode($input, true, 512, JSON_THROW_ON_ERROR);
// If unserialize() is unavoidable for trusted data, forbid objects
$data = unserialize($trusted, ['allowed_classes' => false]);¿Basta con allowed_classes => false?
Bloquea la creación de objetos, el riesgo principal, pero el manual de PHP sigue desaconsejando deserializar entradas no confiables. JSON es la opción segura por defecto.
¿Tiene relación con PHP2Shell?
No. PHP2Shell es un fallo del motor PHP; la inyección de objetos es un fallo del código de la aplicación y existe incluso con PHP totalmente parcheado.
Otras clases de vulnerabilidades PHP
- Inclusión de archivos en PHP (LFI/RFI): qué es y cómo corregirlaLa inclusión de archivos ocurre cuando la entrada del usuario controla la ruta que recibe include o require, lo que permite leer archivos locales (LFI) o, con allow_url_include activado, ejecutar código remoto (RFI).
- SSRF en PHP: qué es y cómo corregirlaLa falsificación de peticiones del lado del servidor (SSRF) ocurre cuando una app PHP descarga una URL controlada por el usuario, lo que permite alcanzar servicios internos o endpoints de metadatos de la nube a través de su servidor.
- XSS en PHP: qué es y cómo prevenirloEl cross-site scripting (XSS) ocurre cuando una página PHP imprime en HTML datos controlados por el usuario sin escapar, de modo que el script de un atacante se ejecuta en el navegador de otros visitantes.
- Exposición de phpinfo(): por qué importa y cómo corregirlaUna página phpinfo() pública revela la versión exacta de PHP, los módulos cargados, las rutas y a menudo variables de entorno o secretos, lo que ayuda a los atacantes a apuntar a fallos como PHP2Shell.
Fuentes
Los enlaces externos salen de este sitio. No alojamos código de explotación.
- unserialize() — PHP Manual
- json_decode() — PHP Manual
- PHP Object Injection — OWASP
- CWE-502: Deserialization of Untrusted Data — MITRE CWE