A03: Fallas en la Cadena de Suministro de Software
¿Qué es una falla de supply chain?
Las fallas de supply chain ocurren cuando una aplicación incorpora riesgo a traves de dependencias, sistemas de build, CI/CD, o por como fluyen los artefactos y credenciales en el pipeline.
OWASP 2025 amplió esta categoría mas alla de “componentes vulnerables” hacia fallas mas amplias en dependencias, sistemas de build y flujo de artefactos.
Fallo tipico en Laravel
- Confianza ciega en paquetes de Composer.
- Sin revision de dependencias.
- Paquetes desactualizados, abandonados o comprometidos.
- Sin disciplina de lockfile, sin SBOM, sin checks de seguridad en CI.
Impacto
- Ejecucion remota de codigo o exfiltracion de datos via dependencias comprometidas.
- Dependency confusion / typosquatting con instalaciones maliciosas.
- Builds no reproducibles (CI vs produccion).
- Fuga de credenciales desde CI o pasos de build.
Remediacion en Laravel 12
- Fija dependencias con
composer.lock(commitealo; despliega desde el lockfile). - Ejecuta
composer auditen CI. - Elimina paquetes abandonados/no mantenidos.
- Usa solo paquetes confiables con historial real de mantenimiento.
- Refuerza CI/CD (firmas, ramas protegidas, review gates) y aplica minimo privilegio en pipelines de build/publicacion.
- Separa credenciales de developer, CI y produccion.
- Controla dependencias transitivas (no solo las directas).
Arreglo concreto
Ejecucion rutinaria (y en CI):
composer auditcomposer outdated
Enfoque de patron de diseño
Encapsula SDKs de terceros detras de Adapters para poder cambiar o aislar un vendor comprometido rapidamente. Usa Facades con moderacion alrededor de SDKs; acoplarte directo a paquetes es perezoso y caro despues.
interface Payments{ public function charge(int $amountCents, string $currency, string $token): string;} final class StripePaymentsAdapter implements Payments{ public function __construct(private \Stripe\StripeClient $stripe) {} public function charge(int $amountCents, string $currency, string $token): string { $intent = $this->stripe->paymentIntents->create([ 'amount' => $amountCents, 'currency' => $currency, 'payment_method' => $token, 'confirm' => true, ]); return (string) $intent->id; }}