Fallo crítico en la función extract()
de PHP permite ejecución de código remoto
En abril de 2025, se descubrió una vulnerabilidad crítica en la función extract()
de PHP que permite a los atacantes ejecutar código arbitrario mediante la explotación de fallos de corrupción de memoria. Esta vulnerabilidad afecta a múltiples versiones de PHP y representa un riesgo significativo para aplicaciones que utilizan esta función con datos controlados por el usuario.
¿Quién está en riesgo?
Los principales afectados por esta vulnerabilidad son:
- Desarrolladores de aplicaciones web en PHP que usan
extract()
con entradas externas como$_POST
,$_GET
,$_REQUEST
o cualquier dato controlado por el usuario. - Sitios web que ejecutan versiones vulnerables de PHP, especialmente aquellos que no han sido actualizados recientemente.
- Plataformas CMS, frameworks o plugins que emplean
extract()
de forma insegura. - Entornos compartidos o servidores web expuestos a internet, donde la explotación podría permitir al atacante comprometer múltiples aplicaciones o incluso el servidor completo.
Naturaleza de la vulnerabilidad
La funciónextract()
de PHP importa variables de un array al ámbito actual. Cuando se usa con la bandera EXTR_REFS
, las variables se importan como referencias. Si se sobrescriben variables que ya existen en el ámbito actual y contienen objetos, PHP llama a zval_ptr_dtor
para liberar el valor anterior.
En este proceso, si el método mágico __destruct()
del objeto modificado interactúa con las variables afectadas, puede inducir condiciones de double-free (PHP 5.x) o use-after-free (PHP 7.x y 8.x), dependiendo de la versión.
Esto abre la puerta a la corrupción del heap y eventualmente a la ejecución de código arbitrario.
¿Cómo sería el proceso de explotación?
Un ciberdelincuente podría aprovechar esta vulnerabilidad siguiendo los siguientes pasos:
- Identificación del uso inseguro de
extract()
: Mediante técnicas como fuzzing, ingeniería inversa o revisión de código fuente público, el atacante identifica partes del código que llaman aextract()
con datos controlables (como parámetros HTTP). - Diseño de una carga maliciosa: El atacante crea un array malicioso que sobrescriba una variable previamente definida que contiene un objeto con un destructor personalizado (
__destruct()
). - Manipulación del heap: Aprovechando las particularidades del recolector de basura de PHP y el comportamiento de
zval_ptr_dtor
, el atacante orquesta una secuencia específica que desencadena el acceso a memoria previamente liberada (use-after-free). - Ejecución arbitraria de código: Finalmente, mediante técnicas de heap spraying o introducción de payloads en memoria, el atacante ejecuta código arbitrario, eludiendo mecanismos como
disable_functions
oopen_basedir
.
¿Cúal podría ser el objetivo del ataque?
- Tomar control total del servidor web.
- Instalar puertas traseras (backdoors).
- Filtrar información confidencial (archivos, credenciales, tokens).
- Realizar movimientos laterales dentro de la infraestructura.
¿Cómo podemos evitarlo?
- Manteniendo actualizado PHP a la última versión donde la vulnerabilidad ha sido corregida.
- Evitando el uso de
extract()
, especialmente con datos de usuario. - Auditando el código heredado y eliminando prácticas que impliquen la importación dinámica de variables.
- Empleando herramientas de análisis estático para detectar patrones peligrosos relacionados con
extract()
.
En definitiva, desde hace tiempo la función extract()
ha representado un riesgo constante debido a su comportamiento impredecible cuando se usa con variables no confiables. Esta vulnerabilidad crítica refuerza la necesidad de prácticas de codificación seguras y una revisión continua del código fuente en aplicaciones PHP, ya que ignorarlo puede llevar a disgustos significativos en cuanto a la seguridad.