Check your Laravel dependencies for known vulnerabilities with composer audit
· 3 min read
Your Laravel app is mostly other people's code. A typical project pulls in a hundred or more Composer packages, and any one of them can have a published security advisory. Updating your own code carefully does not help if a dependency from three years ago has a known remote code execution bug.
The good news is that Composer can check this for you with a single command.
Run composer audit
From the project directory:
composer audit
Composer compares the exact package versions in your composer.lock against the advisory database and lists any that match. For each one it shows the package, the advisory title, the CVE if there is one, the affected versions and a link.
Two variants are worth knowing:
composer audit --locked
--locked audits the versions in composer.lock rather than what is currently installed in vendor/, which is what you want on a build machine that has not installed anything.
composer audit --no-dev
--no-dev ignores development-only packages. Use it when you are checking what actually runs in production.
The command exits with a non-zero status when it finds advisories, which is what makes it usable in automation.
Reading the output
An advisory does not always mean you are exploitable. Read it:
- Is the vulnerable code path reachable in your app? A flaw in an image-processing feature you never call matters less than one in request parsing.
- Is it a
require-devpackage? Dev tools are not on your production server. - Is there a fixed version? The advisory lists it. Most of the time the fix is a minor bump.
Treat anything with a high severity in a runtime package as a "fix this week" item, and do not let the list grow.
Fix it
Update the affected package and see what changes:
composer update vendor/package --with-dependencies
composer audit
Run your tests, then deploy. If the update is blocked because another package pins an old version, composer why-not vendor/package 2.0 tells you which one is in the way.
Make it automatic
A one-time audit goes stale the day after, because new advisories are published all the time. Run it on every push in CI, for example as a GitHub Actions step:
- name: Audit dependencies
run: composer audit --locked --no-dev
Many teams also run it on a schedule, such as weekly, so a project nobody touched still gets checked.
Abandoned packages
A package whose maintainer has stopped working on it will never receive a fix, however serious the next bug is. composer audit reports abandoned packages as well. Plan to replace them rather than carry them indefinitely.
Check without installing anything
If you just want to know where a project stands, you can paste a composer.lock file into the free PHPGuard scan. It runs the same composer audit check against that file and lists the advisories it finds, with severity and links. Nothing is stored afterwards.
For a server you run, the PHPGuard agent runs a dependency audit on the Laravel apps it finds there every day and emails you when a finding turns critical, so you do not depend on remembering to look.
Checklist
composer audit --locked --no-devin CI on every push.- A weekly scheduled run for projects that rarely change.
- Critical advisories in runtime packages get fixed quickly, not queued indefinitely.
- Abandoned packages have a replacement plan.
Check your own site
The free PHPGuard scan checks for exposed .env and .git files, missing security headers and SSL problems in seconds. For continuous monitoring from inside your server, start the 14-day free trial (no card required).
More articles
-
A Laravel production checklist for your own VPS
Everything to verify before and after you put a Laravel app on a server you manage yourself: web server, configuration, permissions, HTTPS, queues, backups and monitoring.
-
How to monitor a Laravel queue worker so it doesn't silently die
A dead queue worker looks like a healthy site: pages load, but emails and jobs never run. How to keep the worker alive with systemd, restart it on deploy, and get alerted when it stops.