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/lang
  • laravel-lang/attributes
  • laravel-lang/http-statuses
  • laravel-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, require ni create-project.
  • La comprobación también se hace en composer install: si una versión se marca como malware después de generar tu composer.lock, la siguiente instalación falla. Así te enteras.
  • composer audit informa 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 update y composer require. composer install sigue instalando exactamente lo que dice tu composer.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-cooldown en 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

  1. 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 cooldown
    

    La protección está en el cliente: un Composer antiguo en una imagen de CI olvidada no te protege.

  2. Ejecuta composer audit de forma periódica, y en tu CI antes de desplegar:

    composer audit
    composer audit --locked   # comprueba el composer.lock sin necesidad de instalar
    
  3. Sube siempre el composer.lock al repositorio y despliega con composer install, nunca con composer update. Así en producción se instala exactamente lo que has probado.

  4. Revisa los cambios del composer.lock en cada actualización. Una dependencia nueva que no esperabas es una señal de alarma.

  5. Valora activar el cooldown de un día en los proyectos de clientes.

  6. 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.

Fuentes