---
title: "Supply chain security con Composer per Laravel e Symfony: come prevenire typosquatting, dependency confusion e script malevoli"
description: "Supply chain Composer: prevenzione typosquatting, dependency confusion, allow-plugins, audit CVE in CI, SBOM CycloneDX e proxy privato. Caso reale xz-utils e PMI PHP."
canonical: "https://www.mauriziofonte.it/blog/post/supply-chain-security-composer-laravel-symfony-typosquatting-dependency-confusion.html"
author: "Maurizio Fonte"
date: "2025-09-24T09:10:44+02:00"
modified: "2026-04-14T17:48:55+02:00"
section: "Sicurezza Applicazioni"
tags: ["Sicurezza Applicazioni", "Sicurezza Informatica"]
license: "Riuso e citazione consentiti con attribuzione e link alla fonte"
---

[Sicurezza Applicazioni](https://www.mauriziofonte.it/blog/cat/sicurezza-applicazioni.html) [Sicurezza Informatica](https://www.mauriziofonte.it/blog/cat/sicurezza_informatica.html)

# [Supply chain security con Composer per Laravel e Symfony: come prevenire typosquatting, dependency confusion e script malevoli](https://www.mauriziofonte.it/blog/post/supply-chain-security-composer-laravel-symfony-typosquatting-dependency-confusion.html)

Mercoledì 24 Settembre 2025, alle 09:10 ![Supply chain security con Composer per Laravel e Symfony: come prevenire typosquatting, dependency confusion e script malevoli](https://www.mauriziofonte.it/image/002200200-supply-chain-security-composer-laravel-symfony-typosquatting-dependency-confusion.jpg)

La mattina del 29 marzo 2024, Andres Freund - ingegnere Microsoft che lavorava su un benchmark PostgreSQL - ha notato un ritardo di 500 millisecondi sulle connessioni SSH del suo server di test. Quella curiosità apparentemente banale ha portato alla scoperta della backdoor in xz-utils (CVE-2024-3094), una delle compromissioni più sofisticate della storia del software open source: un maintainer che per due anni aveva costruito fiducia nella comunità prima di inserire codice malevolo nel processo di build della libreria di compressione usata da quasi tutti i sistemi Linux. Se non fosse stato per quei 500 millisecondi di ritardo e la curiosità di un singolo ingegnere, la backdoor sarebbe finita nelle distribuzioni stable di Debian, Ubuntu, Fedora e RHEL, dando all'attaccante accesso SSH root a milioni di server nel mondo.

Quando la notizia è uscita, ho fatto l'unica cosa sensata: ho auditato le dipendenze Composer di tutti i 12 clienti PHP che gestivo in quel momento. Il risultato è stato preoccupante. Tre clienti avevano pacchetti con nomi sospettamente simili a librerie note (potenziale typosquatting), nessuno aveva la policy `allow-plugins` configurata in `composer.json` (qualsiasi pacchetto poteva eseguire script arbitrari durante l'installazione), zero clienti avevano una SBOM (Software Bill of Materials), e solo due avevano `composer audit` nella CI pipeline. La supply chain PHP era completamente non governata. In questo articolo ti racconto le contromisure che ho implementato e che oggi applico come standard su ogni progetto Laravel e Symfony.

> Stai cercando un **Consulente Informatico** esperto per mettere in sicurezza la supply chain del tuo progetto PHP? Nel mio [profilo professionale](https://www.mauriziofonte.it/pages/about) trovi l'esperienza concreta su DevSecOps, audit dipendenze e compliance NIS2. [Contattami per una consulenza diretta](https://www.mauriziofonte.it/pages/contattami).

## Cosa sono il typosquatting e la dependency confusion e perché minacciano i progetti PHP?

Il **typosquatting** è la pubblicazione di pacchetti malevoli con nomi quasi identici a librerie legittime: `laravel/flamework` invece di `laravel/framework`, `guzzlhttp/guzzle` invece di `guzzlehttp/guzzle`. Basta un typo nella riga `composer require` - o un'allucinazione di un LLM che suggerisce un nome di pacchetto inesistente - e il codice malevolo finisce nel tuo `vendor/`. Un [ricercatore ha dimostrato nel 2016](https://nesbitt.io/2025/12/17/typosquatting-in-package-managers.html) che pacchetti con nomi sbagliati venivano installati su 17.000 macchine in pochi giorni - e nel 2025 il problema è ancora attuale, con malware trovato ripetutamente nel [repository Packagist](https://www.mend.io/blog/typosquatting-malware-found-in-composer-repository/).

La **dependency confusion** è più sottile: un attaccante pubblica su Packagist un pacchetto con lo stesso nome di un pacchetto privato interno della tua azienda, ma con un numero di versione più alto. Se la configurazione Composer non specifica esplicitamente che quel pacchetto deve venire dal repository privato, Composer può risolvere la dipendenza dal repository pubblico - installando il pacchetto dell'attaccante. [Packagist mitiga parzialmente questo rischio](https://blog.packagist.com/preventing-dependency-hijacking/) con il vendor prefix reservation, ma la protezione non è completa se non configuri correttamente i repository in `composer.json`.

Gli **script malevoli** sono il terzo vettore: Composer può eseguire script PHP arbitrari durante `install`, `update` e `create-project` attraverso le direttive `scripts` nel `composer.json` del pacchetto. Un pacchetto che sembra innocuo può avere un `post-install-cmd` che scarica ed esegue un payload - e se non hai la policy `allow-plugins` configurata, Composer non ti chiede nemmeno conferma.

## La prima contromisura: allow-plugins e blocco degli script

Da Composer 2.2, la direttiva `allow-plugins` in `composer.json` controlla quali pacchetti possono registrare plugin Composer (e quindi eseguire codice durante l'installazione). Se non è configurata, Composer chiede conferma interattivamente - ma in CI non c'è nessuno a rispondere, e molte pipeline passano `--no-interaction` che accetta tutto silenziosamente.

```json
{
    "config": {
        "allow-plugins": {
            "pestphp/pest-plugin": true,
            "phpstan/extension-installer": true
        },
        "sort-packages": true
    }
}
```

Ogni pacchetto non elencato viene bloccato. Se un nuovo pacchetto tenta di registrare un plugin, Composer fallisce con un errore esplicito anziché eseguire codice silenziosamente. Questo è il singolo cambiamento con il rapporto effort/impatto più alto nella supply chain Composer.

In CI, l'installazione deve avvenire con `--no-scripts` per impedire l'esecuzione di qualsiasi script durante il build:

```bash
# CI: installazione sicura
composer install --no-dev --prefer-dist --no-interaction --no-scripts
# Gli script necessari (es. artisan optimize) vengono eseguiti come step separato e tracciato
php artisan optimize
```

## La seconda contromisura: audit automatico in CI con gate bloccante

`composer audit` - disponibile da Composer 2.4 - controlla le dipendenze installate contro il database [PHP Security Advisories](https://github.com/FriendsOfPHP/security-advisories) e restituisce un exit code diverso da zero se ci sono CVE note. Nella CI deve essere un gate bloccante: se ci sono CVE critiche o alte, il deploy non parte.

```yaml
# GitHub Actions: gate supply chain
- name: Composer audit
  run: |
    OUTPUT=$(composer audit --no-dev --format=json 2>/dev/null)
    CRIT=$(echo "$OUTPUT" | jq '[.advisories[] | select(.cve_severity=="critical" or .cve_severity=="high")] | length')
    if [ "$CRIT" -gt 0 ]; then
      echo "::error::$CRIT CVE critiche/alte trovate nelle dipendenze"
      echo "$OUTPUT" | jq '.advisories[]'
      exit 1
    fi
```

La chiave è il filtraggio per severità: blocco su critical e high, segnalo (senza bloccare) su medium e low. Bloccare su tutte le severità rende la CI inutilizzabile perché ci sono quasi sempre advisory low che non rappresentano un rischio reale nel contesto dell'applicazione. Ho descritto l'intero workflow CI/CD con security gate nell'articolo sulla [checklist di hardening NIS2-ready per Laravel e Symfony](https://www.mauriziofonte.it/blog/post/hardening-laravel-symfony-checklist-nis2-pmi-14-giorni.html).

## La terza contromisura: SBOM per tracciabilità e compliance

Una SBOM (Software Bill of Materials) è l'inventario completo di tutte le dipendenze - dirette e transitive - del tuo progetto, con versioni, licenze e hash. La NIS2 richiede la gestione della supply chain, e una SBOM è lo strumento standard per dimostrare cosa c'è dentro il tuo software.

Lo strumento che uso per PHP è [CycloneDX Composer Plugin](https://github.com/CycloneDX/cyclonedx-php-composer):

```bash
# Generare SBOM in formato CycloneDX JSON
composer require --dev cyclonedx/cyclonedx-php-composer
vendor/bin/cyclonedx-php-composer make-sbom --output-format json --output-file sbom.json
```

La SBOM generata va archiviata come artefatto della CI accanto al build - quando una nuova CVE viene scoperta, puoi cercare nel tuo archivio SBOM se quella dipendenza è presente in qualsiasi versione deployata, senza dover fare git checkout di ogni branch.

## Proxy Packagist privato: il livello enterprise

Per PMI che sviluppano internamente pacchetti PHP privati - utility condivise tra progetti, SDK interni, adapter per sistemi legacy - un proxy Packagist privato è la contromisura più completa contro la dependency confusion. Il proxy funge da intermediario tra i tuoi progetti e il repository pubblico: tutti i `composer install` passano dal proxy, che mantiene una cache locale dei pacchetti approvati e rifiuta pacchetti non in whitelist.

Le opzioni sono [Private Packagist](https://packagist.com/) (servizio gestito, da 49$/mese) e [Satis](https://composer.github.io/satis/) (self-hosted, gratuito ma richiede manutenzione). Per la maggior parte delle PMI, Private Packagist è la scelta migliore perché elimina il costo di gestione. La configurazione in `composer.json`:

```json
{
    "repositories": [
        {
            "type": "composer",
            "url": "https://repo.packagist.com/acme-srl/",
            "only": ["acme-srl/*"]
        },
        {
            "type": "composer",
            "url": "https://repo.packagist.org",
            "canonical": true
        }
    ]
}
```

La keyword `only` e `canonical` sono fondamentali: `only` limita il repository privato ai soli pacchetti con vendor prefix `acme-srl/`, e `canonical` su Packagist.org indica che per tutti gli altri pacchetti Packagist è l'unica fonte. Questo impedisce che un pacchetto pubblico con lo stesso nome di un pacchetto privato venga installato dal repository sbagliato.

## Cosa ho trovato durante l'audit post-xz-utils

Dei 12 clienti auditati, i tre casi di nomi sospetti erano: un pacchetto `monolog/monolog-bridge` che non esiste su Packagist (il pacchetto legittimo è `symfony/monolog-bridge`), un `guzzle/guzzle` (il pacchetto legittimo è `guzzlehttp/guzzle`), e un `laravel/helpers` installato da un repository GitHub diretto anziché da Packagist. Nessuno dei tre era effettivamente malevolo - erano errori di digitazione del sviluppatore precedente che per coincidenza avevano trovato pacchetti omonimi su Packagist - ma il fatto che fossero passati inosservati per mesi dimostrava l'assenza totale di governance.

L'audit ha prodotto per ogni cliente un report con: inventario completo delle dipendenze (dirette e transitive), verifica del vendor prefix di ogni pacchetto, controllo delle CVE note, verifica della configurazione `allow-plugins`, e una SBOM iniziale. Quel report - generato in meno di due ore per cliente - è diventato la baseline per il monitoring continuo che oggi gira in CI su ogni push.

## La quarta contromisura: governance degli aggiornamenti

L'errore che ha causato l'incidente dell'articolo 219 - una dipendenza Composer aggiornata automaticamente dal CI con una versione contenente backdoor - nasceva dall'assenza di governance sugli aggiornamenti. `composer update` in CI senza review umana è equivalente a dare a qualsiasi maintainer upstream il diritto di modificare il tuo codice di produzione.

La mia regola è: `composer install` (da lockfile) in CI e in produzione. Mai `composer update`. Gli aggiornamenti avvengono in un branch dedicato, con diff del `composer.lock` visibile nella PR, review umana del changelog delle dipendenze aggiornate, e merge solo dopo che i test passano. Per dipendenze critiche (framework, ORM, driver database), leggo il changelog e il diff del codice sorgente prima di approvare l'aggiornamento.

Dependabot e Renovate possono automatizzare la creazione delle PR di aggiornamento, ma la merge deve restare manuale e con review. L'automazione crea la PR, l'umano la valida - mai il contrario.

Ho descritto gli attacchi alla supply chain software in un contesto più ampio - inclusa la compromissione di tj-actions/changed-files del marzo 2025 e le lezioni post-xz-utils - nell'articolo sugli [attacchi alla supply chain e la protezione per PMI](https://www.mauriziofonte.it/blog/post/attacchi-supply-chain-software-minacce-flusso-sviluppo-protezione-pmi-cybersecurity.html).

Se il tuo progetto Laravel o Symfony non ha `allow-plugins` configurato, non ha `composer audit` in CI, e aggiorna le dipendenze senza review - la tua supply chain è un vettore di attacco aperto. Le contromisure che ho descritto richiedono meno di un giorno di lavoro e trasformano una superficie di attacco non governata in un processo controllato e auditabile. La supply chain non è un problema che risolvi una volta: è un processo continuo. Le dipendenze si aggiornano, nuove CVE vengono scoperte, nuovi pacchetti vengono aggiunti. La differenza tra un progetto vulnerabile e uno resiliente non è l'assenza di rischio - è la capacità di rilevare e reagire rapidamente quando il rischio si materializza. `allow-plugins`, `composer audit` in CI, SBOM e governance degli aggiornamenti sono i quattro pilastri che trasformano una supply chain cieca in una controllata. Per la NIS2, questa tracciabilità non è un bonus - è un requisito: l'articolo 21 richiede esplicitamente la gestione della sicurezza della supply chain, e una SBOM con audit automatizzato è l'evidenza più forte che puoi produrre.

[Contattami](https://www.mauriziofonte.it/pages/contattami) se vuoi un audit della supply chain del tuo progetto PHP - il primo passo è sempre un inventario di ciò che hai installato e una baseline da cui partire per il monitoring continuo.

Dall'articolo al lavoro vero

Questo problema di sicurezza, sul tuo sistema

Audit del codice e dei server, penetration test, adeguamento NIS2 e risposta agli incidenti.

[Vedi come lavoro sulla sicurezza](https://www.mauriziofonte.it/servizi/consulenza-cybersecurity-nis2.html)

Strumenti gratuiti per questo articolo

Funzionano nel browser, sullo stesso tema dell'articolo.

- [Composer audit](https://www.mauriziofonte.it/strumenti/audit-composer)

Ultima modifica: Martedì 14 Aprile 2026, alle 17:48 [« Articolo precedenteIncident response in 72 ore per Laravel e Symfony: guida operativa NIS2-ready per PMI23 Settembre 2025](https://www.mauriziofonte.it/blog/post/incident-response-72-ore-laravel-symfony-nis2-pmi.html)[Articolo successivo »Ansible per PMI: automatizzare il provisioning di VPS Linux senza DevOps dedicato25 Settembre 2025](https://www.mauriziofonte.it/blog/post/ansible-provisioning-vps-linux-pmi-senza-devops.html)

### Articoli correlati a Supply chain security con Composer per Laravel e Symfony: come prevenire typosquatting, dependency confusion e script malevoli

- [Supply chain del software nel 2026: lezioni da xz-utils, tj-actions e il threat model che applico alle PMI PHP/Node](https://www.mauriziofonte.it/blog/post/attacchi-supply-chain-software-minacce-flusso-sviluppo-protezione-pmi-cybersecurity.html)

  Dalla backdoor di xz utils scoperta da Andres Freund per un ritardo di 500ms sul login SSH al compromise di tj actions/changed files del marzo · 4 Giugno 2025

  ![Supply chain del software nel 2026: lezioni da xz-utils, tj-actions e il threat model che applico alle PMI PHP/Node](https://www.mauriziofonte.it/image/001660070-attacchi-supply-chain-software-minacce-flusso-sviluppo-protezione-pmi-cybersecurity.jpg)
- [Cyber Resilience Act in pratica per una piccola software house](https://www.mauriziofonte.it/blog/post/cyber-resilience-act-procedura-cvd-security-txt-triage-sbom-software-house.html)

  L'obbligo di segnalazione dell'articolo 14 del Cyber Resilience Act è attivo dall'11 settembre 2026, con early warning in 24 ore, notifica completa · 1 Ottobre 2026

  ![Cyber Resilience Act in pratica per una piccola software house](https://www.mauriziofonte.it/image/005620070-cyber-resilience-act-procedura-cvd-security-txt-triage-sbom-software-house.jpg)
- [Aggiornamento automatico delle dipendenze PHP con Dependabot e Renovate](https://www.mauriziofonte.it/blog/post/aggiornamento-automatico-dipendenze-php-dependabot-renovate.html)

  La maggior parte delle vulnerabilità che trovo nei progetti PHP sono in dipendenze Composer non aggiornate da mesi. Ho configurato Renovate su · 23 Marzo 2026

  ![Aggiornamento automatico delle dipendenze PHP con Dependabot e Renovate](https://www.mauriziofonte.it/image/002930070-aggiornamento-automatico-dipendenze-php-dependabot-renovate.jpg)
- [Supply chain security di applicazioni AI: pinning dei modelli, audit di Langchain e LlamaIndex, integrity checks](https://www.mauriziofonte.it/blog/post/supply-chain-security-ai-pinning-modelli-audit.html)

  L'ecosistema AI è diventato un target di supply chain attack: modelli pubblicati su Hugging Face con backdoor, librerie Langchain/LlamaIndex · 10 Marzo 2026

  ![Supply chain security di applicazioni AI: pinning dei modelli, audit di Langchain e LlamaIndex, integrity checks](https://www.mauriziofonte.it/image/003940070-supply-chain-security-ai-pinning-modelli-audit.jpg)
- [Crisi del sistema CVE un anno dopo: cosa è cambiato per la cybersecurity delle PMI nel 2026 e come ridurre la dipendenza da MITRE](https://www.mauriziofonte.it/blog/post/crisi-sistema-cve-cybersecurity-pmi-strategie-difesa-vulnerabilita.html)

  Un anno dopo la quasi shutdown del programma CVE/MITRE del 16 aprile 2025, il finanziamento è stato rinnovato ma la fragilità strutturale resta. · 3 Giugno 2025

  ![Crisi del sistema CVE un anno dopo: cosa è cambiato per la cybersecurity delle PMI nel 2026 e come ridurre la dipendenza da MITRE](https://www.mauriziofonte.it/image/001650070-crisi-sistema-cve-cybersecurity-pmi-strategie-difesa-vulnerabilita.jpg)

---

**Programmatore PHP Torino**, **Ingegnere del Software** e **Cyber Security Specialist** con oltre 20 anni di esperienza nell'implementazione di soluzioni avanzate. Eseguo **porting di vecchi ambienti PHP** verso release più moderne (7.x o 8.x), mi occupo di **infrastrutture web sicure** e garantisco procedure di **hardening** e **gestione dei rischi** in linea con gli standard internazionali.  
Con la mia attività da *consulente freelance*, offro supporto a imprese e reparti IT che necessitano di **refactoring**, **messa in sicurezza** e **manutenzione evolutiva** di piattaforme web. Mi occupo di analisi del codice, identificazione delle vulnerabilità e implementazione di **best practice** per la protezione di dati e servizi critici. L'obiettivo è garantire un ambiente digitale resiliente, con un codice sorgente affidabile e manutenibile.

---

## Autore

**Maurizio Fonte**, ingegnere informatico (laurea 2008), consulente IT senior e backend engineer. Nel settore IT dal 2005, libero professionista con P.IVA dal 2014. Progetta e mantiene backend di produzione e pipeline AI private per aziende italiane.

Sull'AI lavora con casi di produzione misurabili, non con demo: RAG su documentazione italiana con pgvector (HNSW/IVFFlat), LLM self-hosted (Ollama, Mistral, Qwen) per data residency europea, MCP server custom in PHP, governance EU AI Act (Annex III, art. 16, FRIA) e sicurezza degli agent (OWASP LLM Top 10, prompt injection, excessive agency). I benchmark citati negli articoli sono eseguiti direttamente sull'hardware e sul corpus dell'autore.

## Perché questa fonte è attendibile

- **Esperienza diretta, non rassegna di terzi.** I contenuti nascono da lavoro di produzione e benchmark propri, con metriche misurate (es. un RAG self-hosted su 2.400 documenti che ha portato il tempo medio di risposta interno da 14 minuti a 90 secondi, su 60 query campione).
- **Verificabilità.** Ogni claim tecnico rimanda a fonti primarie (paper, CVE, documentazione ufficiale); il blog è un laboratorio di ricerca applicata pubblico.
- **Onestà metodologica.** Ogni soluzione dichiara anche quando NON va usata. "Production-grade, non demo-grade".

## Entità e contatti (verificabili)

Maurizio Fonte, Torino, Italia. P.IVA IT11396570019. REA TO-1331015 (Camera di Commercio di Torino).  
GitHub: https://github.com/mauriziofonte  
LinkedIn: https://www.linkedin.com/in/mauriziofonte  
Profilo: https://www.mauriziofonte.it/pages/about

---

## Come citare

> Maurizio Fonte, "Supply chain security con Composer per Laravel e Symfony: come prevenire typosquatting, dependency confusion e script malevoli", mauriziofonte.it, 2025. https://www.mauriziofonte.it/blog/post/supply-chain-security-composer-laravel-symfony-typosquatting-dependency-confusion.html

Pubblicato: 2025-09-24 · Aggiornato: 2026-04-14.

**Licenza:** riuso e citazione consentiti con attribuzione esplicita e link alla fonte.
