---
title: "Composer 2.10: bloqueo de malware y políticas de dependencias"
excerpt: "Composer 2.10 trae bloqueo de malware nativo, un objeto config.policy unificado para advisories, paquetes abandonados y malware, e inmutabilidad de versiones estables. La respuesta del ecosistema PHP a los ataques de supply chain de 2026."
date: "2026-06-01T10:00:00.000Z"
category: "PHP"
seo_title: "Composer 2.10: bloqueo de malware y políticas de dependencias en PHP"
seo_description: "Composer 2.10 añade bloqueo de malware nativo (feed de Aikido), el objeto config.policy para malware, advisories y paquetes abandonados, inmutabilidad de versiones y el flag --no-blocking. Qué cambia y qué hacer hoy."
author:
  name: "angel cruz"
  picture: "https://angelcruzdevcdn.nyc3.cdn.digitaloceanspaces.com/images/me/angel-cruz.png"
ogImage:
  url: "/images/open-graph/composer-2-10-bloqueo-malware-politicas-dependencias.png"
---

**Composer 2.10 ya está disponible y trae el cambio de seguridad más importante en años para el ecosistema PHP: bloqueo de malware nativo y un sistema unificado de políticas de dependencias.** Composer es el gestor de dependencias estándar de PHP, y esta versión convierte la protección contra ataques de supply chain en comportamiento por defecto de la herramienta, en lugar de dejarla como responsabilidad del desarrollador.

No es una mejora cosmética: es la respuesta directa a los ataques de supply chain que golpearon a Packagist durante 2026, como el de `laravel-lang` (22 de mayo de 2026) o el de `intercom/intercom-php` (30 de abril de 2026).

En este artículo veo qué cambia realmente, cómo se configura el nuevo objeto `config.policy`, y qué conviene hacer hoy mismo en tus proyectos.

## Por qué llega ahora: los ataques de 2026

El contexto importa, porque explica cada decisión de diseño de esta versión. Según el blog de Packagist, durante 2026 hubo varios ataques de supply chain contra el ecosistema PHP, ejecutados a través de cuentas de GitHub comprometidas y tokens de acceso robados. Dos casos concretos:

- **`laravel-lang`** (22 de mayo de 2026): se publicaron versiones maliciosas tras un secuestro de cuenta.
- **`intercom/intercom-php`** (30 de abril de 2026): compromiso similar basado en credenciales.

El patrón común es el más peligroso de todos: el **re-tagging**. El re-tagging es reescribir una etiqueta (tag) de git existente para cambiar el código al que apunta sin cambiar el número de versión. El atacante no publicaba un paquete nuevo, sino que reescribía una versión que ya era de confianza y que miles de proyectos tenían fijada en su `composer.lock`, inyectándole malware. Una versión que ayer era segura, hoy traía una puerta trasera bajo el mismo número.

Composer 2.10 ataca exactamente ese vector.

## Bloqueo de malware nativo

La función central de esta versión es la detección de malware integrada, alimentada por el feed de **Aikido** (licencia CC-BY 4.0). Funciona así:

> "Flagged versions are removed from the resolution pool, so they cannot be installed via composer update, composer require or composer create-project."

En claro: las versiones marcadas como maliciosas **se eliminan del pool de resolución**. No se pueden instalar con `composer update`, `composer require` ni `composer create-project`.

Lo más importante es que la protección **también corre durante `composer install`**:

> "A malicious release that slipped into a lockfile will not be silently pulled in on CI runs or in production deployments."

Esto es clave. Si un release malicioso se coló en tu `composer.lock`, no se va a instalar de forma silenciosa en CI ni en producción. Justo el escenario del re-tagging que describí arriba.

## composer audit ahora detecta malware

El comando `composer audit` se actualizó para reportar malware además de las advisories de seguridad de siempre:

```bash
# Falla por defecto si encuentra malware en el árbol de dependencias
composer audit
```

> "The same versions are surfaced by composer audit, which fails the audit when finding malware by default."

Junto con esto cambió el comportamiento de los exit codes (un detalle a tener en cuenta en CI):

> "composer audit exit codes now use `0` for success and `1` when the audit fails."

Si tienes un step de CI que corre `composer audit`, revisa que estés interpretando bien el código de salida: `0` es éxito, `1` es fallo.

## config.policy: un solo objeto para todas las políticas

Aquí está el cambio estructural. Composer 2.10 introduce el objeto **`config.policy`**, que reemplaza la configuración anterior bajo `config.audit` y unifica tres políticas integradas bajo una misma estructura:

| Política | Qué cubre |
|----------|-----------|
| `malware` | Versiones marcadas como maliciosas |
| `advisories` | Versiones con vulnerabilidades de seguridad conocidas |
| `abandoned` | Paquetes marcados como abandonados |

Cada política comparte la misma estructura, con tres opciones: `block`, `audit` e `ignore`. Y cada una llega con defaults sensatos:

| Política | Update | Audit | Install |
|----------|--------|-------|---------|
| **malware** | bloqueado | falla | bloqueado |
| **advisories** | bloqueado | falla | instalable (para evaluación) |
| **abandoned** | solo lo reporta el audit | reporta | no bloqueado |

La lógica detrás de los defaults es razonable: el malware se bloquea en todos lados sin excepción; una advisory te frena en el update y el audit, pero te deja instalar la versión si necesitas evaluarla; y un paquete abandonado solo se reporta, porque "abandonado" no significa "inseguro".

### Políticas personalizadas

Además de las tres integradas, puedes definir tus propias políticas apuntando a una fuente HTTPS. Por ejemplo, una lista interna de paquetes vetados por tu organización:

```json
{
    "config": {
        "policy": {
            "company-policy": {
                "sources": [
                    { "type": "url", "url": "https://example.com/bad-pkgs.json" }
                ],
                "audit": "fail"
            }
        }
    }
}
```

Esto abre la puerta a políticas corporativas centralizadas sin depender de herramientas externas.

### Saltarse el bloqueo cuando hace falta

Si necesitas instalar algo bloqueado de forma puntual (por ejemplo, para reproducir o analizar un problema), existe el flag `--no-blocking`:

```bash
composer install --no-blocking
```

También funciona como variable de entorno, útil en entornos donde no controlas el comando directamente:

```bash
COMPOSER_NO_BLOCKING=1 composer install
```

Mi recomendación: úsalo solo de forma local y consciente, nunca en CI ni en producción. El bloqueo está ahí por una razón.

## Inmutabilidad de versiones estables

Esta es la pieza que cierra el círculo contra el re-tagging. A partir de ahora, **las versiones etiquetadas como estables no pueden reescribirse silenciosamente** mediante un re-tag en git. Una versión publicada queda fija: si el contenido de un tag cambia, deja de ser válido en lugar de instalarse como si nada.

Combinado con el bloqueo durante `install`, esto significa que el escenario de `laravel-lang` (reescribir una versión que ya estaba instalada en miles de `composer.lock`) deja de ser viable de forma silenciosa.

## Deprecación del source fallback

Composer 2.10 deprecó el comportamiento de **source fallback**, por el riesgo de seguridad que implica cuando la descarga de un artefacto falla en repositorios privados. Hay una nueva opción `source-fallback` para reactivar el comportamiento legacy si de verdad lo necesitas, pero **se elimina por completo en Composer 2.11**. Conviene ir migrando ya.

## Otras mejoras de la versión

No todo es seguridad. La 2.10 trae también un par de mejoras de ergonomía que vale la pena conocer:

**Wildcards en `--with`.** Ahora puedes restringir varias dependencias de un namespace en una sola pasada:

```bash
composer update --with "acme/*:^2.0"
```

**`--require` en `create-project`.** Puedes añadir dependencias extra al crear un proyecto:

```bash
composer create-project acme/skeleton my-project --require="acme/extra-bundle:^1.0"
```

**`--bump-after-update` más preciso.** Ahora solo hace bump de los paquetes que realmente se actualizaron, no de todo el `composer.json`.

A esto se suman optimizaciones en el autoloading de plugins y una reducción del uso de memoria del `PoolOptimizer`.

## Lo que viene (roadmap de Packagist)

El equipo de Packagist dejó claro que la 2.10 es un paso dentro de un plan más grande. Esto todavía no está disponible, pero está anunciado:

- **Política de antigüedad mínima (cooldown):** rechazar la instalación de versiones publicadas hace muy poco, para dar margen a que se detecte malware antes de que llegue a producción.
- **MFA obligatorio** en Packagist.org, con el estado de MFA visible en los perfiles de maintainer y registrado en el transparency log.
- **Organizational Package Ownership**, para reemplazar las cuentas compartidas (uno de los grandes vectores de los ataques de 2026).
- **Flujo de release escalonado con FIDO2** para paquetes con base de usuarios grande.
- **Hosting directo de artefactos** con provenance SLSA y attestations de Sigstore, alineándose con OpenSSF Level 3 y SLSA L3-L4.

Es una hoja de ruta seria. Vale la pena seguirla si mantienes paquetes propios.

## Qué hacer hoy

Sin teoría, lo accionable:

1. **Actualiza Composer a 2.10**: `composer self-update`.
2. **Corre `composer audit`** en tus proyectos y en tu pipeline de CI. Revisa que el step interprete bien los exit codes (`0` éxito, `1` fallo).
3. **Si mantienes paquetes en Packagist, habilita MFA ahora.** La propia gente de Packagist lo pide de forma explícita: *"If you maintain any package on Packagist.org and don't have MFA enabled, please enable it now."*
4. **Confía en los defaults de `config.policy`.** Están bien pensados; solo toca la configuración si tienes una necesidad real.
5. **Commitea tu `composer.lock`.** Sigue siendo tu primera línea de reproducibilidad, y ahora el bloqueo durante `install` lo respalda. Si todavía tienes dudas sobre por qué, lo expliqué en detalle en [La importancia del archivo composer.lock en PHP](/post/importancia-composer-lock-php).

## Preguntas frecuentes

### ¿Cómo actualizo a Composer 2.10?

Con `composer self-update`. Si lo instalaste vía package manager del sistema (apt, brew, etc.), actualízalo por esa misma vía.

### ¿El bloqueo de malware me puede romper un deploy en producción?

Puede frenar un `composer install` si detecta una versión marcada como maliciosa en tu `composer.lock`, y eso es justamente lo que quieres. No bloquea instalaciones legítimas: solo las versiones que están en el feed de malware. Si te frena, es señal de que tenías un release comprometido fijado.

### ¿De dónde salen los datos de malware?

Del feed de **Aikido** (licencia CC-BY 4.0), integrado en los metadatos de Packagist.org desde marzo de 2026. Packagist dejó abierta la puerta a sumar más proveedores con licencias libres adecuadas.

### ¿`config.policy` reemplaza a `config.audit`?

Sí. El objeto `config.policy` consolida bajo una misma estructura lo que antes estaba en `config.audit`, y suma las políticas de malware y paquetes abandonados junto con las advisories.

### ¿Puedo desactivar el bloqueo temporalmente?

Sí, con el flag `--no-blocking` o la variable de entorno `COMPOSER_NO_BLOCKING`. Úsalo solo de forma local y puntual, nunca en CI ni en producción.

### ¿Qué es el re-tagging y por qué importa tanto?

Es reescribir una etiqueta (tag) de git existente para cambiar el código que apunta sin cambiar el número de versión. Fue el vector de los ataques de 2026: una versión que ya estaba instalada en miles de proyectos se reescribía con malware. La inmutabilidad de versiones estables de Composer 2.10 corta ese vector.

## En resumen

| Cambio | Estado |
|--------|--------|
| Bloqueo de malware en update/require/create-project | Nuevo |
| Bloqueo de malware durante `install` (protege el lockfile) | Nuevo |
| `composer audit` detecta malware | Nuevo |
| Exit codes de `composer audit` (`0`/`1`) | Cambio de comportamiento |
| Objeto `config.policy` unificado | Nuevo (reemplaza `config.audit`) |
| Políticas personalizadas vía HTTPS | Nuevo |
| Flag `--no-blocking` / `COMPOSER_NO_BLOCKING` | Nuevo |
| Inmutabilidad de versiones estables | Nuevo |
| Deprecación de source fallback | Deprecado (se elimina en 2.11) |
| Wildcards en `--with` | Nuevo |
| `--require` en `create-project` | Nuevo |

Composer 2.10 no es una versión más. Es el momento en el que el ecosistema PHP movió la seguridad de supply chain de "responsabilidad del desarrollador" a "comportamiento por defecto de la herramienta". Actualiza, corre `composer audit`, y si mantienes paquetes, habilita MFA hoy.

## Fuentes

- [Malware Blocking and Dependency Policies in Composer 2.10 (Laravel News)](https://laravel-news.com/malware-blocking-and-dependency-policies-in-composer-210)
- [Composer 2.10 Release (Packagist Blog)](https://blog.packagist.com/composer-2-10-release/)
- [An Update on Composer & Packagist Supply Chain Security (Packagist Blog)](https://blog.packagist.com/an-update-on-composer-packagist-supply-chain-security/)
- [Aikido malware feed (CC-BY 4.0)](https://www.aikido.dev/)
</content>
</invoke>

---

## Sitemap

Índice completo del sitio: [/sitemap.md](https://angelcruz.dev/sitemap.md)

Canónico HTML: [https://angelcruz.dev/post/composer-2-10-bloqueo-malware-politicas-dependencias](https://angelcruz.dev/post/composer-2-10-bloqueo-malware-politicas-dependencias)
