Skip to main content

Dependency Audit: npm audit and composer audit

Security · 29.09.2026

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.

← Back to Knowledge Base Ask Support