Current situation: PHP2Shell. Two critical PHP vulnerabilities (CVSS 9.2) allow malicious code without login. Patches since 21 October 2026.What to do now →

composer audit: checking dependencies for vulnerabilities

How developers use composer audit to find known security vulnerabilities in libraries, automate the check and avoid typical deployment mistakes.

Last updated 5 min readGuides

In short: composer audit compares the packages of your PHP project with known security advisories and shows affected versions. Run the command with every build and regularly on the production state. Important after PHP2Shell: the check covers libraries, not the PHP interpreter itself.

Why dependencies need attention right now

Modern PHP applications consist largely of third-party code. A shop based on Symfony or a portal built with Laravel quickly brings in several dozen to hundreds of packages, many of them indirectly through other packages. Any of these libraries can contain a vulnerability. The OWASP Top 10 therefore lists outdated and vulnerable components as a risk category of their own.

In October 2026, PHP2Shell showed how quickly a critical vulnerability spreads. The two vulnerabilities CVE-2026-109618 and CVE-2026-109619 do affect PHP itself and not Composer packages. In those days, however, many teams reviewed their entire chain and found that they did not know the state of their dependencies exactly.

This gap in the overview can be closed with little effort. Composer already ships the matching tool in current versions.

What composer audit checks and what it does not

The command reads the installed packages or the lock file and queries known security advisories for these packages. For each hit it shows the package, affected version range, severity, advisory identifier and a link to the description.

Layer Checked by composer audit? How to check instead
Composer packages in the project yes composer audit
PHP interpreter (e.g. PHP2Shell) no Package status, hosting provider confirmation
PHP extensions from the system no The distribution's package management
JavaScript packages in the frontend no Tool of the respective package manager
Your own application code no Code review, security audit

The command also considers indirect dependencies, that is, packages you never requested yourself but that come along via other packages. Vulnerabilities often lie unnoticed precisely there, because nobody on the team knows these packages. Newer Composer versions also point out packages that their authors have marked as abandoned. Such packages generally no longer receive fixes and should be replaced.

A clean result therefore means only that no known advisory exists for the installed package versions. The tool does not find unknown vulnerabilities or flaws in your own code. How to check the PHP status yourself is described in the article Checking the PHP version and patch status correctly.

Running composer audit and reading the results

In the project directory, one command is enough. The variants differ in what is checked and how the result is output.

# Check installed packages
composer audit

# Check only the lock file, e.g. in the build without installed packages
composer audit --locked

# Leave out development dependencies (state as on the server)
composer audit --no-dev

# Machine-readable output for evaluation or ticket system
composer audit --format=json > audit-$(date +%F).json

If the command finds vulnerabilities, it ends with an error code. That is intended, because it makes an automated build abort. Assess each hit: is the package in use on the server, is the affected function used, is there a fixed version?

# Which direct dependencies are outdated?
composer outdated --direct
# Why is a particular package installed?
composer why vendor/paket
# Update selectively, with dependencies
composer update vendor/paket --with-dependencies

Test every update in a staging environment. Security updates within the same major version are usually uncritical, whereas a new major version can require changes to the code.

Automating the check

A one-off call helps little, because new vulnerabilities become known all the time. Therefore integrate composer audit in two places: in the build pipeline with every change, and in a regular check of the production state, even if nothing changes in the code.

A simple script for a daily run on the build or check server can look like this:

#!/bin/sh
# Daily audit of the delivered state (adjust path)
cd /srv/build/meine-anwendung || exit 1
if ! composer audit --locked --no-dev --format=plain > /var/log/composer-audit.log 2>&1; then
  logger -t composer-audit "Lücken in meine-anwendung gefunden, siehe /var/log/composer-audit.log"
fi

Forward the message from the system log to your monitoring, your internal mailbox or your ticket system. What matters is that someone is responsible for assessing the messages. An audit whose warnings nobody reads does not protect.

Tip

In composer.json, set under config.platform.php the PHP version that runs on the server. Composer then resolves only packages that fit this state, and composer check-platform-reqs shows deviations.

Delivering cleanly: deployment without side effects

The route to the server also affects security. A few basic rules have proved their worth:

  • Put composer.lock into the repository and run only composer install on the server, never composer update.
  • Install with --no-dev so that test and debug tools do not end up on the production server.
  • Keep the vendor/ folder outside the web root so that it is not directly reachable via a URL.
  • Run composer validate in the build to detect faulty or contradictory entries early.
composer validate --strict
composer install --no-dev --prefer-dist --classmap-authoritative --no-interaction

Also watch the support status of the PHP version itself. Libraries increasingly require current PHP branches. Anyone still stuck on PHP 8.1 or older gets no official updates for PHP itself any more and often can no longer install newer package versions with security fixes. Planning for this is described in the guide PHP end of life: risks of outdated versions. Framework-specific notes are at Securing Laravel applications.

How does PHP SOS help?

  • We record the state of all dependencies and assess hits by actual use.
  • We set up automated checks in build and operation, with clear responsibility for findings.
  • We plan and test updates, even when new major versions require changes.
  • On request, we also check your own code and configuration, where no automatic tool looks.

A review by third parties is described in the service Security audit and penetration test.

Frequently asked questions

Does composer audit also find PHP2Shell?

No. composer audit checks the packages in your project, not the PHP interpreter on the server. PHP2Shell sits in PHP itself and is fixed only by an update of PHP and a restart of all PHP processes.

Does composer.lock have to go into the repository?

For applications, yes. The lock file records exactly which versions are installed. Only then does composer audit check the state that actually runs on the server, and every deployment installs the same versions.

What should I do if no update exists for an affected package?

Check whether your project uses the affected function at all, and document the assessment. If there is no fix, a replacement package, your own patch or a temporary safeguard at server level come into question.

How often should I run composer audit?

With every build and additionally on a regular basis, for example daily, even without code changes. New vulnerabilities are reported continually, and a state that was clean yesterday can be affected today.

Sources

Immediate contact

Every hour counts. Write to us now.

Briefly describe your system, PHP version and observation. We will get back to you, clarify the situation and work remotely until the incident is closed and documented.

Immediate help