Skip to main content

Dependency Audit: npm audit and composer audit

Security · · 4 min read
Illustration for “Dependency Audit: npm audit and composer audit”

Why check dependencies for vulnerabilities

Dependency auditing means checking every connected library against known vulnerabilities from public databases such as the GitHub Advisory Database and the National Vulnerability Database. A WordPress site pulls in dozens of npm packages for theme builds and composer packages for plugins; a vulnerability in one of them opens a path to compromising the whole site, even if the core code is written carefully.

In 2026, supply chain attacks are common practice: attackers publish malicious code in a package with a name similar to a popular library (typosquatting), or hijack a maintainer's account and ship an infected update. Regular dependency auditing is a mandatory part of a server security checklist.

npm audit: checking Node.js packages

The command has been built into npm since version 6 and needs no installation:

cd /var/www/myapp
npm audit

The report groups vulnerabilities by severity: low, moderate, high, critical. For each one it lists the package, the fixed version, and the dependency path — which top-level package pulls in the vulnerable version. Automatic fixing without bumping major versions:

npm audit fix

The --force flag on npm audit fix can bump a dependency's major version and break the API — never run it on production without testing on a copy of the site first.

composer audit: checking PHP packages

Starting with Composer 2.4 the command works out of the box:

cd /var/www/myapp
composer audit

Composer checks the contents of composer.lock against the FriendsOfPHP Security Advisories database and prints a list of CVEs with a description and the recommended version. Unlike npm, composer does not offer an automatic fix — the version must be bumped manually:

composer require vendor/package:^2.5 --update-with-dependencies

After updating, always run the test suite: PHP packages often change method signatures even in minor releases.

Automating the audit in CI

A manual run is easy to forget, so the audit belongs in the pipeline: GitHub Actions, GitLab CI, or a simple cron job on the build server. Example CI step:

- name: Security audit
  run: |
    npm audit --audit-level=high
    composer audit

The --audit-level=high parameter stops the build only for high and critical vulnerabilities — so low-severity findings do not block every release, while critical issues never pass unnoticed.

What to do when there is no fix

Sometimes a patch has not shipped yet, or the package has been abandoned by its maintainer. Options:

  • Find a fixed fork and temporarily switch to it via overrides in package.json or replace in composer.json.
  • Shrink the attack surface: if the vulnerable code path is rarely used, disable the corresponding feature through configuration.
  • Add a compensating control at the server level — a ModSecurity WAF rule that blocks requests typical of the exploit.
  • Document the risk and set a review deadline — silently ignoring a vulnerability is not an option.

Regular audit checklist

  • npm audit and composer audit run on every deploy, not once a quarter.
  • Critical and high vulnerabilities block the CI build.
  • package-lock.json and composer.lock are committed — dependency versions are pinned.
  • Updates are tested on a copy of the site before going to production.
  • The list of unfixed vulnerabilities with compensating measures is reviewed every month.

Dependency auditing closes vulnerabilities in other people's code, but it does not replace baseline server protection: set up a secure PHP configuration and a general server security checklist, and after an incident use the hacked site recovery guide.

Was this article helpful?
← Back to Knowledge Base Ask Support