What composer.lock Actually Does

If you work with PHP, you know composer.lock. It is the file that Composer generates after resolving your dependency tree, and it pins every single package — direct and indirect — to an exact version. When a teammate or your CI pipeline runs composer install, they get the exact same packages you had. No surprises, no version drift, no "it works on my machine" issues.

This is fundamental to reproducible builds. Your composer.json declares version constraints like "guzzlehttp/guzzle": "^7.0", but composer.lock records the precise resolved version: 7.5.1. Every developer, every staging server, every production deploy gets 7.5.1 — not 7.5.2, not 7.6.0.

The lock file also captures the full transitive dependency tree. If Guzzle requires psr/http-client, guzzlehttp/promises, and symfony/deprecation-contracts, all of those appear in your lock file with their exact versions too. A typical WordPress project with a dozen plugins and a framework like Laravel can easily have 150 to 300 locked packages in its composer.lock.

This determinism is a feature. But it comes with a serious blind spot that most PHP developers overlook entirely.

The False Sense of Security

"We locked our dependencies, so we're safe." This is one of the most dangerous assumptions in PHP development. Locking your dependencies guarantees consistency, but it does not guarantee security. The moment you lock a version, the security clock starts ticking against you.

Here is the reality: vulnerabilities are discovered after code is released. A package you locked six months ago at version 3.2.1 may have had zero known CVEs at the time. Today, it might have three — including a critical remote code execution. Your composer.lock still says 3.2.1. Your production server still runs 3.2.1. The vulnerability is sitting there, deployed and exposed.

This is not a theoretical risk. The PHP ecosystem sees dozens of new security advisories every month through the FriendsOfPHP/security-advisories database and OSV.dev. Every one of those advisories potentially affects projects that locked the vulnerable version weeks or months earlier.

The lock file gives you a snapshot in time. It does not give you a security guarantee. The only way to know if your locked dependencies are still safe is to actively audit them against current vulnerability databases — and to keep doing so continuously.

Transitive Dependencies: The Attack Surface You Don't See

Most developers have a reasonable grasp of the packages they explicitly require in composer.json. You chose Guzzle for HTTP, Monolog for logging, PHPMailer for email. You might even track their changelogs. But here is where composer.lock vulnerabilities become truly insidious: transitive dependencies.

When you require guzzlehttp/guzzle, you also get:

That is seven additional packages you never explicitly chose. Each one is a potential attack vector. Each one can have CVEs filed against it. And most developers never check them — because they never knowingly installed them.

Now multiply this across a full project. A Laravel application typically has 70+ direct packages in composer.json. After Composer resolves the tree, composer.lock can contain 250 to 400 packages. You chose 70. Composer chose the other 180 to 330. Any of those can harbor a vulnerability, and you are responsible for all of them.

A real-world example: in 2022, guzzlehttp/psr7 had a header parsing vulnerability (CVE-2022-24775) that allowed improper header handling. This was a transitive dependency for thousands of projects that never directly required it. If you were only watching your direct dependencies, you missed it entirely.

How to Audit composer.lock: The composer audit Command

Since Composer 2.4, there is a built-in command for running a composer security audit against your locked dependencies:

composer audit

This command reads your composer.lock, queries the Packagist security advisories database, and reports any packages with known vulnerabilities. The output looks something like this:

Found 3 security vulnerability advisories affecting 2 packages:
+-------------------+---------------------------------------------+
| Package           | guzzlehttp/psr7                             |
| CVE               | CVE-2023-29197                              |
| Title             | Improper header parsing                     |
| URL               | https://github.com/advisories/GHSA-wxmh-65f7-jcvw |
| Affected versions | >=2,<2.4.5|>=1,<1.9.1                       |
| Reported at       | 2023-04-17T00:00:00+00:00                   |
| Severity          | high                                        |
+-------------------+---------------------------------------------+
| Package           | symfony/http-kernel                         |
| CVE               | CVE-2023-46734                              |
| Title             | Potential XSS in CodeExtension              |
| URL               | https://github.com/advisories/GHSA-xxx      |
| Affected versions | >=6.3,<6.3.8                                |
| Reported at       | 2023-11-10T00:00:00+00:00                   |
| Severity          | medium                                      |
+-------------------+---------------------------------------------+

Understanding Severity Levels

The composer audit output includes a severity level for each advisory. Understanding these is critical for prioritization:

Using composer audit in CI/CD

The most effective way to use composer audit is to integrate it into your CI/CD pipeline so it runs on every pull request:

# GitHub Actions example
- name: Security audit
  run: composer audit --format=json
  continue-on-error: false

The --format=json flag outputs machine-readable JSON, and the command returns a non-zero exit code when vulnerabilities are found — making it perfect for CI gates. You can also use --abandoned=report to flag packages that are no longer maintained, which is another significant risk factor.

Real Examples of PHP Dependency Vulnerabilities

To understand why continuous monitoring of composer.lock vulnerabilities matters, consider these real cases that affected thousands of PHP projects:

Guzzle SSRF Vulnerabilities (2022)

Guzzle, the most popular PHP HTTP client with over 400 million downloads, was hit by multiple SSRF (Server-Side Request Forgery) vulnerabilities in 2022. CVE-2022-29248 allowed cookie manipulation across domains, and CVE-2022-31042 enabled unauthorized header forwarding. These were critical because Guzzle is used by virtually every major PHP framework and CMS — Laravel, Drupal, Magento, and countless WordPress plugins all depend on it either directly or transitively.

If you had locked Guzzle 7.4.4 in your composer.lock before these disclosures, your production system was vulnerable until you explicitly updated. The lock file was doing exactly what it was supposed to — keeping you on an exact version — but that exact version was now a known attack vector.

Symfony Security Advisories

Symfony components are the backbone of modern PHP. They are used inside Laravel, Drupal, and as standalone libraries. Symfony regularly discloses vulnerabilities across its ecosystem:

Because Symfony is split into dozens of small components, and because many frameworks pull in specific Symfony packages as transitive dependencies, a single Symfony advisory can affect projects that have never explicitly required Symfony. You see symfony/http-kernel in your lock file, but you never put it there — Laravel did.

Monolog Injection Patterns

Monolog is the de facto logging library for PHP, used by nearly every modern PHP application. While Monolog itself has a strong security record, its handler ecosystem creates injection risks. The SocketHandler, NativeMailerHandler, and SwiftMailerHandler all accept user-controllable data that, if unsanitized, can lead to log injection, SMTP header injection, or SSRF.

These are not traditional CVEs but configuration-level vulnerabilities that compound when combined with other dependency issues. A vulnerable version of a Monolog handler adapter, locked in your composer.lock, becomes a persistent risk if you never revisit it.

The Agency Scaling Problem

If you are an individual developer maintaining one or two PHP projects, running composer audit manually is manageable. You SSH into your server, run the command, read the output, update what needs updating. It takes ten minutes.

Now consider the reality of a web agency. You have 30 client sites. Each one has its own composer.lock. Each one was built at a different time, with different package versions. Some are on Laravel 9, some on Laravel 10, one legacy project is still on Laravel 8. Five of them use WordPress with WooCommerce and various plugins, each pulling in their own dependency trees.

That is 30 different lock files, potentially containing 5,000 to 10,000 individual package version pins across all projects. Manually auditing each one means:

Even if each audit only takes 10 minutes, that is 5 hours of work — just for a single pass. And you need to do this regularly, ideally daily, because new CVEs are published constantly. No agency has an engineer dedicated to spending 5 hours every day running composer audit across client sites.

The result is predictable: audits don't happen. Dependencies drift. Vulnerabilities accumulate. When a critical CVE drops — like the Guzzle SSRF issues — the agency scrambles to figure out which of their 30 clients is affected, often missing some entirely.

This is not a discipline problem. It is a scaling problem. Manual processes break when the number of projects grows, and agencies always grow their project count faster than their team size.

Continuous Monitoring with OptiBot

This is exactly the problem CVE OptiBot was built to solve. Instead of running composer audit manually across dozens of projects, you upload each project's composer.lock to OptiBot and let the platform handle continuous scanning.

Here is how it works:

Upload and Forget

For each client project, upload the composer.lock file to OptiBot. The platform parses every package and version — direct dependencies and transitive ones alike. No code access is needed. No repository integration required. Just the lock file.

Daily Automated Scans

OptiBot scans all your projects daily against the OSV.dev vulnerability database, which aggregates data from GitHub Security Advisories, the PHP Security Advisories Database, and the National Vulnerability Database (NVD). When a new CVE is published that affects any package in any of your lock files, you know about it immediately.

Unified Dashboard

Instead of reading 30 separate composer audit outputs, you get a single dashboard showing every vulnerability across all your projects. Filter by severity, by project, by package name. See at a glance which clients are affected by the latest Symfony advisory. Identify which projects share the same vulnerable Guzzle version.

Email Alerts

When a new CVE hits any of your client projects, OptiBot sends an email alert with the affected project, the vulnerable package, the severity level, and the recommended fix version. No more manual checking. No more missed advisories.

PDF Security Reports

For agencies that need to report security status to clients, OptiBot generates PDF security reports per project. These are client-ready documents showing the current vulnerability status of their dependencies — professional, clear, and up to date.

The core value is simple: one upload per project replaces hours of manual auditing. And because the scanning is continuous, you catch new vulnerabilities within 24 hours of disclosure instead of discovering them weeks later during an ad-hoc check.

Best Practices for PHP Dependency Security

Whether or not you use a monitoring platform, these practices will significantly reduce your exposure to composer.lock vulnerabilities:

1. Update Dependencies Regularly

Set a cadence — biweekly or monthly — to run composer update and test the results. The longer you go without updating, the larger the version jump when you finally do, and the higher the risk of breaking changes. Small, regular updates are far safer than big-bang updates every six months.

2. Run composer audit in CI

Add composer audit as a CI step that fails the build when vulnerabilities are found. This prevents new deployments from shipping with known-vulnerable dependencies. Combined with branch protection rules, this creates a hard gate that catches issues before they reach production.

# GitLab CI example
security_audit:
  stage: test
  script:
    - composer audit --no-interaction
  allow_failure: false

3. Monitor in Production

CI catches vulnerabilities at deploy time, but CVEs are discovered between deploys. A project you deployed last Tuesday might be hit by a critical advisory published on Thursday. Without continuous production monitoring, you won't know until the next deploy — which could be weeks away.

This is where a platform like OptiBot complements CI-based auditing. CI protects the deploy pipeline. OptiBot protects the running application.

4. Review New Dependencies Before Adding Them

Before running composer require on a new package, take five minutes to evaluate it:

5. Use composer.lock in Production, Not composer.json

Always deploy with composer install (which reads the lock file), never with composer update (which resolves fresh versions). This should be enforced in your deployment scripts. Running composer update in production is a recipe for untested code reaching your servers.

6. Track Abandoned Packages

Run composer audit --abandoned=report periodically. Abandoned packages will never receive security patches, making any future CVE a permanent risk. Replace abandoned packages proactively, before a vulnerability forces an emergency migration.

7. Separate Dev and Production Dependencies

Ensure your test and development tools are in require-dev, not require. Deploy with composer install --no-dev so that packages like PHPUnit, Faker, and debugging tools never reach production. This reduces your production attack surface without any functional cost.

Conclusion: Lock Files Require Active Vigilance

Your composer.lock is doing its job: ensuring deterministic, reproducible builds. But determinism without monitoring means you are deterministically deploying vulnerabilities. The lock file pins versions; it does not validate their safety.

PHP dependency vulnerabilities are a constant, evolving threat. Transitive dependencies expand your attack surface far beyond what you explicitly chose. Manual auditing does not scale beyond a handful of projects. And new CVEs are published every day, affecting packages you locked months ago.

The solution is layered: use composer audit in your CI pipeline to catch issues at deploy time, and use continuous monitoring with a platform like CVE OptiBot to catch issues between deploys. Upload your composer.lock files, let automated scans do the work, and focus your engineering time on building features instead of chasing advisories.

Your lock file should be a source of confidence, not a source of hidden risk. Start monitoring it today.

Ce que fait vraiment composer.lock

Si vous travaillez avec PHP, vous connaissez composer.lock. C'est le fichier que Composer genere apres avoir resolu votre arbre de dependances, et il fixe chaque package — direct et indirect — a une version exacte. Quand un collegue ou votre pipeline CI execute composer install, il obtient exactement les memes packages que vous. Pas de surprises, pas de derive de versions, pas de "ca marche sur ma machine".

C'est fondamental pour des builds reproductibles. Votre composer.json declare des contraintes de version comme "guzzlehttp/guzzle": "^7.0", mais composer.lock enregistre la version precise resolue : 7.5.1. Chaque developpeur, chaque serveur de staging, chaque deploiement en production obtient 7.5.1 — pas 7.5.2, pas 7.6.0.

Le fichier lock capture aussi l'arbre complet des dependances transitives. Si Guzzle necessite psr/http-client, guzzlehttp/promises et symfony/deprecation-contracts, tous ces packages apparaissent dans votre lock file avec leurs versions exactes. Un projet WordPress typique avec une douzaine de plugins et un framework comme Laravel peut facilement contenir 150 a 300 packages verrouilles dans son composer.lock.

Ce determinisme est une fonctionnalite. Mais il s'accompagne d'un angle mort serieux que la plupart des developpeurs PHP ignorent completement.

Le faux sentiment de securite

"On a verrouille nos dependances, donc on est en securite." C'est l'une des hypotheses les plus dangereuses en developpement PHP. Verrouiller vos dependances garantit la coherence, mais cela ne garantit pas la securite. Des l'instant ou vous verrouillez une version, le compteur de securite commence a jouer contre vous.

Voici la realite : les vulnerabilites sont decouvertes apres la publication du code. Un package que vous avez verrouille il y a six mois en version 3.2.1 avait peut-etre zero CVE connue a l'epoque. Aujourd'hui, il en a peut-etre trois — dont une execution de code a distance critique. Votre composer.lock indique toujours 3.2.1. Votre serveur de production execute toujours 3.2.1. La vulnerabilite est la, deployee et exposee.

Ce n'est pas un risque theorique. L'ecosysteme PHP enregistre des dizaines de nouveaux avis de securite chaque mois via la base FriendsOfPHP/security-advisories et OSV.dev. Chacun de ces avis affecte potentiellement des projets qui ont verrouille la version vulnerable des semaines ou des mois plus tot.

Le fichier lock vous donne un instantane dans le temps. Il ne vous donne pas une garantie de securite. La seule facon de savoir si vos dependances verrouillees sont toujours sures est de les auditer activement contre les bases de vulnerabilites actuelles — et de continuer a le faire en permanence.

Les dependances transitives : la surface d'attaque invisible

La plupart des developpeurs connaissent raisonnablement les packages qu'ils requierent explicitement dans composer.json. Vous avez choisi Guzzle pour le HTTP, Monolog pour les logs, PHPMailer pour les emails. Vous suivez peut-etre meme leurs changelogs. Mais c'est la que les vulnerabilites de composer.lock deviennent vraiment insidieuses : les dependances transitives.

Quand vous ajoutez guzzlehttp/guzzle, vous obtenez aussi :

Ce sont sept packages supplementaires que vous n'avez jamais explicitement choisis. Chacun est un vecteur d'attaque potentiel. Chacun peut faire l'objet de CVEs. Et la plupart des developpeurs ne les verifient jamais — parce qu'ils ne les ont jamais sciemment installes.

Multipliez maintenant cela a l'echelle d'un projet complet. Une application Laravel a typiquement plus de 70 packages directs dans composer.json. Apres resolution par Composer, composer.lock peut contenir 250 a 400 packages. Vous en avez choisi 70. Composer a choisi les 180 a 330 autres. N'importe lequel peut cacher une vulnerabilite, et vous etes responsable de tous.

Un exemple concret : en 2022, guzzlehttp/psr7 avait une vulnerabilite de parsing d'en-tetes (CVE-2022-24775) permettant une mauvaise gestion des headers. C'etait une dependance transitive pour des milliers de projets qui ne l'avaient jamais directement requise. Si vous ne surveilliez que vos dependances directes, vous l'avez completement ratee.

Comment auditer composer.lock : la commande composer audit

Depuis Composer 2.4, il existe une commande integree pour lancer un audit de securite Composer sur vos dependances verrouillees :

composer audit

Cette commande lit votre composer.lock, interroge la base de donnees d'avis de securite de Packagist et signale tout package avec des vulnerabilites connues. La sortie ressemble a ceci :

Found 3 security vulnerability advisories affecting 2 packages:
+-------------------+---------------------------------------------+
| Package           | guzzlehttp/psr7                             |
| CVE               | CVE-2023-29197                              |
| Title             | Improper header parsing                     |
| URL               | https://github.com/advisories/GHSA-wxmh-65f7-jcvw |
| Affected versions | >=2,<2.4.5|>=1,<1.9.1                       |
| Reported at       | 2023-04-17T00:00:00+00:00                   |
| Severity          | high                                        |
+-------------------+---------------------------------------------+
| Package           | symfony/http-kernel                         |
| CVE               | CVE-2023-46734                              |
| Title             | Potential XSS in CodeExtension              |
| URL               | https://github.com/advisories/GHSA-xxx      |
| Affected versions | >=6.3,<6.3.8                                |
| Reported at       | 2023-11-10T00:00:00+00:00                   |
| Severity          | medium                                      |
+-------------------+---------------------------------------------+

Comprendre les niveaux de severite

La sortie de composer audit inclut un niveau de severite pour chaque avis. Les comprendre est crucial pour la priorisation :

Utiliser composer audit en CI/CD

La maniere la plus efficace d'utiliser composer audit est de l'integrer a votre pipeline CI/CD pour qu'il s'execute a chaque pull request :

# Exemple GitHub Actions
- name: Audit de securite
  run: composer audit --format=json
  continue-on-error: false

Le flag --format=json produit du JSON lisible par machine, et la commande retourne un code de sortie non-zero quand des vulnerabilites sont trouvees — parfait pour les portes de CI. Vous pouvez aussi utiliser --abandoned=report pour signaler les packages qui ne sont plus maintenus, ce qui constitue un autre facteur de risque significatif.

Exemples reels de vulnerabilites dans les dependances PHP

Pour comprendre pourquoi la surveillance continue des vulnerabilites composer.lock est essentielle, considerez ces cas reels qui ont touche des milliers de projets PHP :

Vulnerabilites SSRF de Guzzle (2022)

Guzzle, le client HTTP PHP le plus populaire avec plus de 400 millions de telechargements, a ete frappe par plusieurs vulnerabilites SSRF (Server-Side Request Forgery) en 2022. CVE-2022-29248 permettait la manipulation de cookies entre domaines, et CVE-2022-31042 permettait le transfert non autorise d'en-tetes. Ces failles etaient critiques parce que Guzzle est utilise par pratiquement tous les frameworks et CMS PHP majeurs — Laravel, Drupal, Magento et d'innombrables plugins WordPress en dependent directement ou transitivement.

Si vous aviez verrouille Guzzle 7.4.4 dans votre composer.lock avant ces divulgations, votre systeme de production etait vulnerable jusqu'a ce que vous fassiez explicitement la mise a jour. Le fichier lock faisait exactement ce qu'il devait faire — vous maintenir sur une version exacte — mais cette version exacte etait desormais un vecteur d'attaque connu.

Avis de securite Symfony

Les composants Symfony sont l'epine dorsale du PHP moderne. Ils sont utilises dans Laravel, Drupal et comme librairies autonomes. Symfony divulgue regulierement des vulnerabilites dans son ecosysteme :

Parce que Symfony est divise en dizaines de petits composants, et parce que de nombreux frameworks tirent des packages Symfony specifiques comme dependances transitives, un seul avis Symfony peut affecter des projets qui n'ont jamais explicitement requis Symfony. Vous voyez symfony/http-kernel dans votre lock file, mais vous ne l'avez jamais mis — c'est Laravel qui l'a fait.

Patterns d'injection Monolog

Monolog est la librairie de logging de facto pour PHP, utilisee par quasiment toute application PHP moderne. Bien que Monolog lui-meme ait un bon bilan securite, son ecosysteme de handlers cree des risques d'injection. Le SocketHandler, NativeMailerHandler et SwiftMailerHandler acceptent tous des donnees controlables par l'utilisateur qui, si non sanitisees, peuvent mener a de l'injection de logs, de l'injection d'en-tetes SMTP ou du SSRF.

Ce ne sont pas des CVEs traditionnelles mais des vulnerabilites au niveau de la configuration qui se cumulent lorsqu'elles sont combinees avec d'autres problemes de dependances. Une version vulnerable d'un adaptateur de handler Monolog, verrouillee dans votre composer.lock, devient un risque persistant si vous ne la revisitez jamais.

Le probleme de scalabilite pour les agences

Si vous etes un developpeur individuel maintenant un ou deux projets PHP, lancer composer audit manuellement est gerab. Vous vous connectez en SSH a votre serveur, lancez la commande, lisez la sortie, mettez a jour ce qui doit l'etre. Ca prend dix minutes.

Considerez maintenant la realite d'une agence web. Vous avez 30 sites clients. Chacun a son propre composer.lock. Chacun a ete construit a un moment different, avec des versions de packages differentes. Certains sont sur Laravel 9, d'autres sur Laravel 10, un projet legacy est encore sur Laravel 8. Cinq d'entre eux utilisent WordPress avec WooCommerce et divers plugins, chacun tirant son propre arbre de dependances.

Ce sont 30 fichiers lock differents, contenant potentiellement 5 000 a 10 000 versions de packages individuelles a travers tous les projets. Auditer manuellement chacun signifie :

Meme si chaque audit ne prend que 10 minutes, c'est 5 heures de travail — juste pour un seul passage. Et vous devez le faire regulierement, idealement quotidiennement, parce que de nouvelles CVEs sont publiees en permanence. Aucune agence n'a un ingenieur dedie a passer 5 heures chaque jour a lancer composer audit sur les sites clients.

Le resultat est previsible : les audits ne sont pas faits. Les dependances derivent. Les vulnerabilites s'accumulent. Quand une CVE critique tombe — comme les problemes SSRF de Guzzle — l'agence se demene pour determiner lesquels de ses 30 clients sont affectes, en en manquant souvent certains.

Ce n'est pas un probleme de discipline. C'est un probleme de scalabilite. Les processus manuels cassent quand le nombre de projets augmente, et les agences augmentent toujours leur nombre de projets plus vite que la taille de leur equipe.

Monitoring continu avec OptiBot

C'est exactement le probleme que CVE OptiBot a ete concu pour resoudre. Au lieu de lancer composer audit manuellement sur des dizaines de projets, vous uploadez le composer.lock de chaque projet sur OptiBot et laissez la plateforme gerer le scan continu.

Voici comment ca fonctionne :

Uploadez et oubliez

Pour chaque projet client, uploadez le fichier composer.lock sur OptiBot. La plateforme analyse chaque package et version — dependances directes et transitives. Aucun acces au code n'est necessaire. Aucune integration de repository requise. Juste le fichier lock.

Scans quotidiens automatises

OptiBot scanne tous vos projets quotidiennement contre la base de vulnerabilites OSV.dev, qui agregue les donnees de GitHub Security Advisories, la PHP Security Advisories Database et la National Vulnerability Database (NVD). Quand une nouvelle CVE est publiee qui affecte un package dans l'un de vos fichiers lock, vous le savez immediatement.

Dashboard unifie

Au lieu de lire 30 sorties composer audit separees, vous avez un seul tableau de bord montrant chaque vulnerabilite a travers tous vos projets. Filtrez par severite, par projet, par nom de package. Voyez d'un coup d'oeil quels clients sont affectes par le dernier avis Symfony. Identifiez quels projets partagent la meme version vulnerable de Guzzle.

Alertes email

Quand une nouvelle CVE touche l'un de vos projets clients, OptiBot envoie une alerte email avec le projet affecte, le package vulnerable, le niveau de severite et la version recommandee pour corriger. Plus besoin de verification manuelle. Plus d'avis manques.

Rapports PDF de securite

Pour les agences qui doivent rendre compte de l'etat de securite a leurs clients, OptiBot genere des rapports PDF de securite par projet. Ce sont des documents prets pour le client montrant l'etat actuel des vulnerabilites de leurs dependances — professionnels, clairs et a jour.

La valeur fondamentale est simple : un upload par projet remplace des heures d'audit manuel. Et parce que le scan est continu, vous detectez les nouvelles vulnerabilites dans les 24 heures suivant leur divulgation au lieu de les decouvrir des semaines plus tard lors d'un controle ad hoc.

Bonnes pratiques pour la securite des dependances PHP

Que vous utilisiez une plateforme de monitoring ou non, ces pratiques reduiront significativement votre exposition aux vulnerabilites composer.lock :

1. Mettez a jour regulierement

Definissez un rythme — bimensuel ou mensuel — pour lancer composer update et tester les resultats. Plus vous attendez sans mettre a jour, plus le saut de version sera important quand vous le ferez enfin, et plus le risque de changements cassants sera eleve. Des petites mises a jour regulieres sont bien plus sures que des mises a jour massives tous les six mois.

2. Lancez composer audit en CI

Ajoutez composer audit comme etape CI qui fait echouer le build quand des vulnerabilites sont trouvees. Cela empeche les nouveaux deploiements d'embarquer des dependances avec des vulnerabilites connues. Combine avec des regles de protection de branches, cela cree une porte dure qui attrape les problemes avant qu'ils n'atteignent la production.

# Exemple GitLab CI
security_audit:
  stage: test
  script:
    - composer audit --no-interaction
  allow_failure: false

3. Monitorez en production

La CI attrape les vulnerabilites au moment du deploiement, mais les CVEs sont decouvertes entre les deploiements. Un projet que vous avez deploye mardi dernier peut etre touche par un avis critique publie jeudi. Sans monitoring continu en production, vous ne le saurez pas avant le prochain deploiement — qui peut etre dans des semaines.

C'est la qu'une plateforme comme OptiBot complete l'audit base sur la CI. La CI protege le pipeline de deploiement. OptiBot protege l'application en cours d'execution.

4. Examinez les nouvelles dependances avant de les ajouter

Avant de lancer composer require sur un nouveau package, prenez cinq minutes pour l'evaluer :

5. Utilisez composer.lock en production, pas composer.json

Deployez toujours avec composer install (qui lit le lock file), jamais avec composer update (qui resout de nouvelles versions). Cela doit etre impose dans vos scripts de deploiement. Lancer composer update en production est la recette pour que du code non teste atteigne vos serveurs.

6. Suivez les packages abandonnes

Lancez composer audit --abandoned=report periodiquement. Les packages abandonnes ne recevront jamais de correctifs de securite, faisant de toute future CVE un risque permanent. Remplacez les packages abandonnes proactivement, avant qu'une vulnerabilite ne force une migration d'urgence.

7. Separez les dependances dev et production

Assurez-vous que vos outils de test et developpement sont dans require-dev, pas dans require. Deployez avec composer install --no-dev pour que des packages comme PHPUnit, Faker et les outils de debugging n'atteignent jamais la production. Cela reduit votre surface d'attaque en production sans aucun cout fonctionnel.

Conclusion : les lock files exigent une vigilance active

Votre composer.lock fait son travail : assurer des builds deterministes et reproductibles. Mais le determinisme sans monitoring signifie que vous deployez des vulnerabilites de maniere deterministe. Le fichier lock fixe les versions ; il ne valide pas leur securite.

Les vulnerabilites des dependances PHP sont une menace constante et evolutive. Les dependances transitives etendent votre surface d'attaque bien au-dela de ce que vous avez explicitement choisi. L'audit manuel ne passe pas a l'echelle au-dela d'une poignee de projets. Et de nouvelles CVEs sont publiees chaque jour, affectant des packages que vous avez verrouilles il y a des mois.

La solution est en couches : utilisez composer audit dans votre pipeline CI pour attraper les problemes au moment du deploiement, et utilisez le monitoring continu avec une plateforme comme CVE OptiBot pour attraper les problemes entre les deploiements. Uploadez vos fichiers composer.lock, laissez les scans automatises faire le travail, et concentrez votre temps d'ingenierie sur la construction de fonctionnalites plutot que la chasse aux avis de securite.

Votre fichier lock devrait etre une source de confiance, pas une source de risques caches. Commencez a le monitorer des aujourd'hui.