Cuando ejecutas composer install, confías en cada paquete que se descarga, y en los paquetes de los que dependen esos paquetes. Un ataque a la cadena de suministro aprovecha precisamente esa confianza: en lugar de atacar tu aplicación, el atacante compromete una dependencia y espera a que seas tú quien la instale.
En 2026 el ecosistema PHP ha sufrido su caso más sonado hasta la fecha, y Composer ha respondido con dos novedades de seguridad que conviene conocer y activar.
Qué pasó con Laravel-Lang
Laravel-Lang es un conjunto de paquetes muy popular con traducciones para Laravel. Entre el 22 y el 23 de mayo de 2026, un atacante comprometió cuatro de ellos:
laravel-lang/langlaravel-lang/attributeslaravel-lang/http-statuseslaravel-lang/actions
Cómo lo hizo
- El atacante creó una copia (fork) del repositorio y añadió el código malicioso en su copia.
- Después creó en el repositorio oficial etiquetas de versión que apuntaban a los commits de su copia. En los repositorios legítimos de Laravel-Lang no se subió ningún commit.
- Resultado: versiones que parecían oficiales instalaban código del atacante. La mayoría de fuentes hablan de más de 700 versiones afectadas; Aikido, en una actualización posterior, cifró en 233 las versiones comprometidas.
Qué hacía el código malicioso
El atacante añadió un archivo src/helpers.php a la sección autoload.files del composer.json de cada paquete. Los archivos de esa sección se cargan en cada petición a tu aplicación, sin que tengas que llamar a nada. Ese archivo era un ladrón de credenciales.
Cómo se resolvió
Packagist retiró las versiones maliciosas y ocultó temporalmente los cuatro paquetes. Después volvieron a estar disponibles, con versiones limpias. Si usas laravel-lang/lang, asegúrate de estar en una versión publicada después del incidente.
Composer 2.10: bloqueo de malware por defecto
Pocos días después, el 28 de mayo de 2026, se publicó Composer 2.10. Por primera vez, Composer bloquea paquetes marcados como malware.
Cómo funciona:
- Las versiones de Packagist.org marcadas como malware no se pueden instalar con
composer update,requirenicreate-project. - La comprobación también se hace en
composer install: si una versión se marca como malware después de generar tucomposer.lock, la siguiente instalación falla. Así te enteras. composer auditinforma del malware y falla por defecto si lo encuentra.- Está activado por defecto y no necesita configuración para los paquetes de Packagist.org. La lista de versiones marcadas la proporciona la empresa de seguridad Aikido.
Políticas por defecto:
| Tipo | Al actualizar (update) |
En composer audit |
Al instalar (install) |
|---|---|---|---|
| Malware | Bloqueado | Falla | Bloqueado |
| Avisos de seguridad | Bloqueado | Falla | Se permite |
| Paquetes abandonados | Se permite | Solo informa | Se permite |
Si alguna vez necesitas saltarte el bloqueo temporalmente, existe la opción --no-blocking (o la variable de entorno COMPOSER_NO_BLOCKING en CI). Úsala solo si sabes exactamente por qué.
Composer 2.11: un periodo de espera para versiones nuevas
Hay un problema que el bloqueo de malware no resuelve: siempre pasa un tiempo entre que se publica una versión maliciosa y se marca como tal. Si actualizas justo en ese intervalo, la instalas.
Para eso, Composer 2.11 (publicado el 29 de octubre de 2026) añade el cooldown: retiene las versiones recién publicadas durante el tiempo que configures antes de permitir instalarlas. No está activado por defecto. Se activa en el composer.json de tu proyecto:
{
"config": {
"policy": {
"cooldown": {
"period": "1 day"
}
}
}
}
El periodo admite valores como "6 hours", "1 day" o "1 week". También puedes definirlo con la variable de entorno COMPOSER_POLICY_COOLDOWN_PERIOD, por ejemplo en tu sistema de integración continua.
Algunos detalles importantes:
- Se aplica en
composer updateycomposer require.composer installsigue instalando exactamente lo que dice tucomposer.lock. - También retrasa los parches de seguridad. Composer no los exime automáticamente, porque un atacante podría usar esa excepción para saltarse el periodo de espera. Si necesitas un parche urgente, usa
--no-cooldownen esa actualización concreta. - Puedes excluir tus propios paquetes con la opción
ignore, por ejemplo"mi-empresa/*".
Composer 2.11 incluye además varias correcciones de seguridad. Por ejemplo, las cabeceras con tokens de la configuración de repositorios ya no se escriben en composer.lock.
Checklist para tus proyectos
-
Actualiza Composer en tu equipo, en los servidores y en las imágenes de CI:
composer self-update composer --version # 2.10 o superior para el bloqueo de malware; 2.11 para el cooldownLa protección está en el cliente: un Composer antiguo en una imagen de CI olvidada no te protege.
-
Ejecuta
composer auditde forma periódica, y en tu CI antes de desplegar:composer audit composer audit --locked # comprueba el composer.lock sin necesidad de instalar -
Sube siempre el
composer.lockal repositorio y despliega concomposer install, nunca concomposer update. Así en producción se instala exactamente lo que has probado. -
Revisa los cambios del
composer.locken cada actualización. Una dependencia nueva que no esperabas es una señal de alarma. -
Valora activar el cooldown de un día en los proyectos de clientes.
-
Usa pocas dependencias: cada paquete que añades es código de un tercero que se ejecuta en tu servidor.
Conclusión
Los ataques a la cadena de suministro no necesitan ningún fallo en tu código: les basta con comprometer un eslabón en el que confías. La buena noticia es que Composer ya incluye defensas importantes; solo hay que mantenerlo actualizado y activarlas.
¿Quieres que revise las dependencias y el proceso de despliegue de tu aplicación Laravel? Escríbeme.