Skip to content
All articles

Keeping PHP Dependencies Safe with Composer: Lock Files, Audits and Updates

Your PHP app runs on dozens of open-source packages. Four Composer habits keep them safe: lock files, audits, replacing abandoned packages and steady updates.

M By · 5 min read
Keeping PHP Dependencies Safe with Composer: Lock Files, Audits and Updates

Most modern PHP applications, from Laravel and Symfony apps to many WordPress plugins, are built on dozens of open-source packages installed with Composer. Keeping them safe takes four habits: commit composer.lock and install from it, run composer audit regularly and in every deployment, replace abandoned packages, and update on a steady schedule instead of once every few years. If your business relies on a custom PHP app, these are the questions to ask your developer, and the checks below take minutes once they are part of the routine.

Why dependencies deserve attention

When you hire someone to build a portal, booking system or internal tool in PHP, a large share of the code running in production was written by other people: frameworks, payment SDKs, PDF generators, email libraries. That is normal and healthy. It also means a vulnerability in any of those packages is a vulnerability in your app, and fixes only reach you when someone updates them.

The good news: Composer has built-in tools that make this manageable, and they are free.

1. Commit composer.lock and install from it

Composer uses two files:

  • composer.json lists the packages your app needs and which version ranges are acceptable (for example ^3.2, meaning any 3.x version from 3.2 up, but not 4.0).
  • composer.lock records the exact versions that were installed and tested.

The Composer documentation says committing the lock file "is important because it will cause anyone who sets up the project" to use the same versions, including production servers and CI systems. In practice:

  • Production deployments should run composer install, which installs exactly what the lock file lists. A typical production command is composer install --no-dev --optimize-autoloader, which skips development-only tools.
  • Only run composer update deliberately, on a developer machine or staging, then test and commit the new lock file. Running update directly on a live server can pull in untested versions.
  • Keep vendor/ out of public reach. It should sit outside the web root, or be blocked by the web server.

2. Use composer audit

composer audit checks your installed packages against published security advisories (from the Packagist.org API by default) and lists any that are affected. It was added in Composer 2.4, and by default Composer also runs an audit automatically after composer update and composer require.

Useful ways to run it:

composer audit                 # check installed packages
composer audit --locked        # check what composer.lock says, without a vendor folder
composer audit --no-dev        # ignore development-only packages
composer audit --format=json   # machine-readable output for CI

It exits with a non-zero code when it finds problems, so you can add it to your deployment pipeline and stop a deploy that would ship a known-vulnerable package.

Newer Composer versions block insecure updates

Since Composer 2.9, Composer blocks package versions with known security advisories during update and require by default, so you cannot accidentally upgrade into a vulnerable release. Recent documentation groups these options under a policy setting (older projects may use the earlier audit settings). If a build suddenly fails after a Composer upgrade, read the message: it is usually pointing at a package you need to update, not a bug. If you must temporarily ignore an advisory, ignore that specific advisory with a written reason and a review date, rather than switching the protection off.

Keep Composer itself current with composer self-update, so you get these protections.

Engineer reviewing a dependency report during a deployment

3. Replace abandoned packages

Package authors can mark a package as abandoned on Packagist, often naming a replacement. An abandoned package won't receive security fixes, so it becomes a growing liability.

  • Composer reports abandoned packages during installs and in composer audit. Since Composer 2.7, the audit treats abandoned packages as a failure by default; the behavior can be adjusted with the --abandoned option (ignore, report or fail).
  • When one shows up, plan the switch to the suggested replacement (or an actively maintained alternative) as part of your next update cycle.
  • Also watch for packages that aren't formally abandoned but haven't had a release in years. They deserve a second look before you build more on them.

4. Update on a steady cadence

Most dependency problems come from waiting too long, when one small update has turned into a major-version migration. A cadence that works for many small teams:

When What
Every deploy composer install from the lock file; composer audit in the pipeline
Monthly composer outdated --direct to see what has newer versions; apply minor and patch updates on staging, test, deploy
Within days of an advisory Update the affected package, test the affected feature, deploy
Quarterly Review abandoned and stale packages; plan major-version upgrades
With each PHP upgrade Confirm every package supports the new PHP version

Automated tools such as GitHub's Dependabot support Composer and can open update pull requests for you, which turns the monthly step into a review rather than a chore.

Keep the number of dependencies reasonable

Every package is code you are trusting. Before adding a new one, a developer should ask whether it is actively maintained, widely used, and really needed. Fewer, well-maintained packages are easier to keep safe.

5. Protect the supply chain

  • Install packages only from trusted repositories (Packagist, or your own private repository) and keep repository URLs on HTTPS.
  • Review lock file changes in pull requests. Unexpected new packages or sources deserve a question.
  • Don't run Composer as root on servers. Run it as the site's own user.
  • Keep secrets out of composer.json and out of the repository; use environment variables or an auth file that isn't committed.

Questions to ask your developer or IT provider

  1. Is composer.lock committed, and does production use composer install?
  2. Does every deployment run composer audit, and does it stop on findings?
  3. Which Composer version do we run, and when was it last updated?
  4. Do we have any abandoned packages, and what is the plan for them?
  5. When were dependencies last updated, and who owns the monthly update?

We can help

Core Florida IT maintains and secures custom PHP applications and the servers they run on for businesses in Miami-Dade and South Florida, with remote support nationwide. If you are not sure when your app's dependencies were last checked, request a free IT assessment and we will review it with you.

Sources

Keep reading

Let's make your IT the strongest part of your business.

Book a free, no-obligation IT assessment. We'll show you exactly where you stand and what to fix first.

Call Free assessment