Le applicazioni PHP non muoiono di vecchiaia, muoiono di manutenzione mancata. In ogni progetto Composer non curato accadono tre cose in silenzio: nuove CVE vengono pubblicate sulle versioni effettivamente installate, autori smettono di mantenere librerie e marcano i pacchetti come abandoned, branch maggiori di framework escono dal security support. Dopo diciotto-ventiquattro mesi di immobilità, l'applicazione è formalmente funzionante ma esposta a vulnerabilità note e patchate da tempo nelle versioni nuove. Questo tool fa emergere quello stato in trenta secondi a partire dal solo manifest.
Cosa controlla l'audit, in concreto. Tre fonti distinte alimentano il triage. (1) Vulnerabilità note (CVE): l'API Packagist Security Advisory aggrega FriendsOfPHP/security-advisories e GitHub Advisory DB; OSV.dev (Open Source Vulnerabilities, gestito da Google) arricchisce ogni advisory con CVSS v3 vector e CWE ID. Coverage: 6.000+ advisory su 1.000+ pacchetti Composer. (2) End-of-life (EOL): endoflife.date pubblica i cicli release dei framework principali con data di fine security support. Pacchetti monitorati: PHP, Laravel (e illuminate/*), Symfony (e ogni symfony/*), Composer stesso, Guzzle, Twig, CakePHP, Drupal, GrumPHP. (3) Abandoned: il flag abandoned di Packagist viene letto per l'unione di tutti i pacchetti citati nelle advisory e dei top 2.000 pacchetti popolari, con cache TTL di 7 giorni. Risultato: 210+ pacchetti effettivamente abbandonati nel dataset.
Differenza fra audit del lock e audit del json. Il composer.lock contiene le versioni esatte risolte: il matcher fa lookup esatto contro l'intervallo affected dell'advisory (es. >=9.0.0,<9.5.6). Il composer.json contiene solo i constraint dichiarati (es. ^9.0): il matcher esegue intersezione fra il constraint utente e l'intervallo affected, segnalando se esiste almeno una versione installabile vulnerabile. Per audit rigorosi usa il lock. Il json è utile per stabilire se il vincolo permetterebbe di scaricare versioni vulnerabili anche con un nuovo composer install domani: lo flagga il triage, ma la verità è in produzione.
Il matcher di constraint è preciso. Non si limita al confronto major: implementa il caret ^X.Y.Z con la regola eccezione per major-zero (^0.5.0 = >=0.5.0 <0.6.0, ^0.0.5 = >=0.0.5 <0.0.6), il tilde ~X.Y, il wildcard X.Y.*, l'hyphen range 1.0 - 2.0, gli operatori >= <= > < =, l'OR || e l'AND comma-or-whitespace, le stability suffix -dev -alpha -beta -RC con priorità lessicografica. La normalizzazione è in DNF (disjunctive normal form) di intervalli e l'intersezione fra constraint è pairwise overlap: stessa semantica di composer/semver PHP, in JS vanilla, senza dipendenze.
Privacy operativa. Il composer.lock rivela la struttura completa di un progetto, le sue dipendenze transitive e gli eventuali pacchetti privati con riferimenti a repository VCS interni. Caricarlo su un servizio terzo per analisi preliminari non è una buona idea, anche con TLS: ogni servizio terzo è un vettore di leak per la mappa delle tue dipendenze. Qui non parte nessuna richiesta con i dati del manifest. Il dataset (16 shard advisory + 1 file EOL + 1 file abandoned) viene scaricato dal browser una sola volta al primo utilizzo e cachato in localStorage per le sessioni successive (invalidazione automatica via SHA-256 sui file pubblici). Audit, parsing e matching: tutto in locale.
Quando il triage statico è il livello giusto. Casi tipici. (a) Review preliminare di un progetto legacy senza accesso al filesystem: il cliente ti incolla il manifest in mail e vuole una valutazione in trenta secondi. (b) Pre-engagement audit per stimare lo sforzo di un eventuale incarico di adeguamento prima di firmare il preventivo. (c) Screen iniziale prima di un assessment cyber serio: definisci la lista dei high/critical da approfondire con esercizio di exploitability assessment, mappatura dei vettori applicabili, verifica della reachability dei codepath. (d) Self-check periodico per il proprietario dell'applicazione che vuole sapere se chi mantiene il codice sta facendo il suo lavoro.
Limite di scope. Il tool segnala CVE pubblicate, EOL noti, abbandoni dichiarati. Non sostituisce un Software Composition Analysis enterprise (Snyk, Mend, Sonatype): non controlla licenze, non genera SBOM CycloneDX, non analizza vulnerabilità di codice non-Composer (binari di sistema, script Node, container base image). Non sostituisce composer audit CLI integrato in pipeline. Non sostituisce un assessment manuale che valuti sfruttabilità reale dei vettori, presenza dei codepath nelle versioni, mitigazioni applicate a livello di hardening. È un triage e si propone come tale.