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.
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.jsonlists 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.lockrecords 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 iscomposer install --no-dev --optimize-autoloader, which skips development-only tools. - Only run
composer updatedeliberately, on a developer machine or staging, then test and commit the new lock file. Runningupdatedirectly 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.

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--abandonedoption (ignore,reportorfail). - 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.jsonand out of the repository; use environment variables or an auth file that isn't committed.
Questions to ask your developer or IT provider
- Is
composer.lockcommitted, and does production usecomposer install? - Does every deployment run
composer audit, and does it stop on findings? - Which Composer version do we run, and when was it last updated?
- Do we have any abandoned packages, and what is the plan for them?
- 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.


