En resumen: las extensiones de PHP son módulos en C que amplían PHP con funciones, por ejemplo controladores de bases de datos (PDO), cifrado (Sodium, OpenSSL) o la caché de bytecode OPcache. El manual de PHP distingue extensiones Core, Bundled, External y PECL. Se cargan mediante extension o zend_extension en el php.ini. Cada extensión se ejecuta en el proceso de PHP con sus permisos. Por eso rige: cargar solo lo que se necesita y actualizarlo junto con PHP.
¿Qué son las extensiones de PHP?
El núcleo de PHP, la Zend Engine, puede ejecutar código, pero buena parte de lo que necesitan las aplicaciones está en las extensiones. Están escritas en C y se compilan dentro de PHP o se cargan al iniciar como biblioteca compartida (.so en Linux, .dll en Windows).
Importante para quienes toman las decisiones: las extensiones no son plugins de la aplicación, sino parte del entorno de ejecución de PHP. Las instala el proveedor de hosting o el administrador del servidor, no la agencia en el CMS. Si falta una extensión, la aplicación suele notificar un error durante la instalación o la actualización.
Igualmente importante es la distinción respecto a los paquetes de Composer. Composer instala bibliotecas escritas en PHP que se encuentran en la carpeta del proyecto, por ejemplo un paquete de correo o de PDF. Las extensiones, en cambio, son código compilado que se carga al iniciar PHP y vale para todas las aplicaciones del servidor. Muchos paquetes de Composer requieren determinadas extensiones y lo indican en su composer.json con entradas como ext-intl o ext-sodium. Quien quiera comprobar si un proyecto encuentra todas las extensiones necesarias puede ejecutar composer check-platform-reqs en la carpeta del proyecto.
¿Qué tipos de extensiones hay?
El manual de PHP agrupa las extensiones en cuatro categorías:
| Grupo | Significado según el manual | Ejemplos del manual |
|---|---|---|
| Core | parte del núcleo de PHP, no se puede desactivar | Arrays, Date/Time, Hash, JSON, PCRE, SPL, Strings |
| Bundled | se distribuyen con PHP | BC Math, Ctype, Fileinfo, Filter, GD, intl, mbstring, PDO, Sessions |
| External | se distribuyen con PHP, necesitan bibliotecas externas | cURL, DOM, GMP, LDAP, OpenSSL, Sodium, Zip |
| PECL | disponibles mediante PECL, en parte con bibliotecas externas | APCu, Memcached, MongoDB, Yaml |
La clasificación puede cambiar. Con PHP 8.4, según la página de la versión, las extensiones IMAP, OCI8, PDO_OCI y pspell se retiraron de la distribución y pasaron a PECL. Quien las use necesita tras la actualización una instalación aparte, que también debe mantenerse.
¿Cómo se cargan las extensiones?
Según el manual, las extensiones compartidas se cargan con la directiva extension en el php.ini; las extensiones Zend, que intervienen más a fondo en el motor, con zend_extension. Ambas solo pueden figurar en el php.ini. El directorio lo fija extension_dir, para el que el manual recomienda una ruta absoluta.
; extensiones normales
extension=pdo_mysql
extension=sodium
extension=intl
; Extensión Zend: OPcache (cargar antes que Xdebug si ambas están activas)
zend_extension=opcache
Distribuciones como Debian y Ubuntu crean para cada extensión un pequeño archivo .ini propio en el directorio de escaneo, por ejemplo en /etc/php/8.3/mods-available/, y la activan para cada SAPI con phpenmod y phpdismod. Cómo lee PHP estos archivos lo explica El php.ini explicado.
Las extensiones se instalan normalmente mediante la gestión de paquetes, por ejemplo como paquete php8.3-intl. Las extensiones PECL pueden compilarse con pecl o phpize. Según el manual, PECL está declarado obsoleto; se recomienda el PHP Installer for Extensions (PIE). Quien compila PHP por completo por su cuenta encontrará indicaciones en Compilar PHP desde el código fuente.
Revisar las extensiones: ¿cuáles están realmente cargadas?
Los siguientes comandos son de solo lectura. Tenga en cuenta que la línea de comandos puede cargar extensiones distintas de las del sitio web.
php -m # módulos de la CLI
php-fpm8.3 -m # módulos de PHP-FPM 8.3 (nombre según la distribución)
php --re sodium | head -n 5 # funciones de una extensión
php --ri opcache # configuración de una extensión
php -r 'var_dump(extension_loaded("intl"));'
En el código, las aplicaciones comprueban con extension_loaded() si hay una extensión disponible y con get_loaded_extensions() cuáles están cargadas:
<?php
$benoetigt = ['pdo_mysql', 'mbstring', 'intl', 'sodium'];
$fehlend = array_diff($benoetigt, array_map('strtolower', get_loaded_extensions()));
echo $fehlend ? 'Fehlt: ' . implode(', ', $fehlend) : 'Alle Erweiterungen vorhanden';
Extensiones y seguridad: menos es más
Las extensiones se ejecutan en el mismo proceso que PHP y con los mismos permisos. Un fallo en una extensión puede ser, por tanto, tan grave como un fallo en el núcleo. De ahí se derivan cuatro reglas:
- Cargar solo lo que se necesita. Cada extensión adicional aumenta la superficie de ataque. Contraste su lista con los requisitos del sistema de la aplicación.
- Actualizar junto con PHP. Las extensiones incluidas llegan con la actualización de PHP. Las extensiones PECL y de terceros necesitan actualizaciones propias y deben ser compatibles con la nueva versión de PHP.
- Herramientas de desarrollo, no en producción. Los depuradores y perfiladores como Xdebug pertenecen solo a los entornos de desarrollo.
- Bloquear funciones de forma selectiva. Donde las extensiones aportan funciones para comandos del sistema, ayuda Usar disable_functions correctamente.
En PHP2Shell, las vulnerabilidades están en el núcleo de PHP, no en una extensión. Desactivar módulos no las cierra; hace falta la actualización a 8.5.12, 8.4.27, 8.3.36 u 8.2.35 con reinicio de todos los procesos de PHP. Tras la actualización debería comprobar si todas las extensiones vuelven a cargarse, porque los módulos que faltan suelen notarse solo en determinadas funciones. Cómo mantener las dependencias bajo control de forma duradera lo describe Mantener las dependencias al día.
¿Cómo ayuda PHP SOS en concreto?
- Inventariar: listamos para cada SAPI todas las extensiones cargadas con su origen y versión.
- Depurar: contrastamos la lista con las necesidades de su aplicación y desactivamos lo superfluo tras una prueba.
- Actualizar: en el marco del refuerzo del servidor llevamos PHP y todas las extensiones de terceros a un estado mantenido.
- Comprobar tras las actualizaciones: verificamos que, tras cada actualización de PHP, vuelvan a cargarse todos los módulos necesarios.
Preguntas frecuentes
¿Cuál es la diferencia entre extension y zend_extension?
Con extension, PHP carga extensiones normales como los controladores de bases de datos. Con zend_extension se cargan, según el manual, extensiones Zend que intervienen más a fondo en el motor, por ejemplo OPcache o Xdebug. Ambas directivas solo pueden figurar en el php.ini.
¿Cómo veo qué extensiones están cargadas?
En la línea de comandos con php -m; para el sitio web, mediante la función get_loaded_extensions() en un archivo de prueba colocado de forma breve o con php-fpm -m de la versión correspondiente. Tenga en cuenta que la CLI y la SAPI web pueden cargar extensiones distintas.
¿Qué es PECL y qué es PIE?
PECL es un directorio de extensiones de PHP que se ofrecen mediante el sistema de paquetes PEAR. Según el manual de PHP, PECL está declarado obsoleto; en su lugar se recomienda el PHP Installer for Extensions (PIE).
¿Cierra PHP2Shell el hecho de desactivar una extensión?
No. Las vulnerabilidades de PHP2Shell están en el núcleo de PHP, no en una extensión que pueda desactivarse. Tener menos extensiones reduce la superficie de ataque en general, pero no sustituye la actualización a una versión corregida.