
Open-source software runs the modern internet. It also quietly runs your business. The average commercial application now contains somewhere between 70% and 90% open-source code, according to multiple software composition analysis reports published over the last few years. That means when you add "just one small npm package" to speed up a feature, you are often pulling in dozens of transitive dependencies written by people you have never met, maintained on schedules you do not control.
Most teams never look. They see a green badge on GitHub, a few thousand stars, and a permissive license, and they run npm install. Then a maintainer burns out, an account gets hijacked, or a "helpful" contributor slips malicious code into a build script. The 2024 XZ Utils backdoor, which was inserted over nearly two years by a trusted contributor, showed exactly how patient and sophisticated supply-chain attacks have become.
This guide walks you through how to audit open-source software before it touches your stack. You will get a repeatable checklist, a worked example with real numbers, a scoring framework, and a comparison of the tools I actually use. The goal is not paranoia. It is a defensible process that takes an hour or two and saves you from a bad week.
Key Takeaways
- Health is not popularity. Star count tells you nothing about whether a project is maintained. Check commit recency, bus factor, and open-issue response times instead.
- Audit the dependency tree, not just the package. A safe library with 40 risky transitive dependencies is a risky library.
- Read the license before the README. A GPL dependency in a proprietary product can force you to open-source your own code.
- Run automated scanners, then verify by hand. Tools like
npm audit, OSV-Scanner, and Snyk catch known CVEs; humans catch social-engineering risk.- Score every candidate on the same rubric so decisions are consistent and reviewable later.
- When the audit fails, a vetted commercial alternative is often cheaper than the risk you would inherit.
Why Auditing Open-Source Software Matters More Than Ever
The dependency you adopt today becomes an attack surface you own tomorrow. When a vulnerability lands in a widely used package, the clock starts immediately. Log4Shell (CVE-2021-44228) went from disclosure to mass exploitation in hours because so many teams had no idea Log4j was even in their build.
There are three distinct risks you are auditing for, and it helps to keep them separate in your head:
- Security risk: known CVEs, malicious code, insecure defaults, or a compromised publishing account.
- Maintenance risk: the project is abandoned, single-maintainer, or so complex nobody can safely fork it.
- Legal risk: a license that conflicts with how you plan to ship, or unclear ownership of contributed code.
A package can be flawless on one axis and disastrous on another. A beautifully maintained library under a strong copyleft license might still be a legal landmine for a closed-source SaaS. This same logic applies to any third-party component, which is why we cover related vetting in our guides on testing an MCP server before connecting it to your AI agent and vetting a Chrome extension after the latest security patches.
The 8-Point Open-Source Audit Checklist
Here is the process I run on every dependency that will handle data, touch production, or be hard to remove later. Work top to bottom. Any hard failure is a reason to stop.
- Confirm the source of truth. Find the canonical repository, not a mirror or a typosquatted package. Verify the package name on the registry matches the linked repo, and check the maintainer's identity. Typosquatting (for example
electorninstead ofelectron) is one of the most common attack vectors. - Check maintenance signals. Look at the date of the last commit, the release cadence, and how many maintainers have merge rights. A project with one maintainer and no releases in 18 months is a maintenance risk regardless of quality.
- Measure the bus factor. If a single person authored 95% of commits, ask what happens when they stop. The XZ incident proved that even projects with a "trusted" second contributor can be compromised.
- Read the license carefully. Match it against your distribution model. MIT, BSD, and Apache-2.0 are permissive. GPL and AGPL are copyleft and can force disclosure of your own code. Check transitive dependencies too, since one AGPL package deep in the tree can taint everything.
- Scan for known vulnerabilities. Run
npm audit,pip-audit, OSV-Scanner, or Snyk against the full dependency tree. Note both the count and the severity, and check whether fixes are available. - Inspect the dependency tree depth. Run
npm ls --allor generate a software bill of materials (SBOM). A package that adds 200 transitive dependencies is 200 new trust relationships. - Review install and build scripts. Malicious packages frequently hide payloads in
postinstallhooks. Openpackage.jsonand read anyscriptsthat run automatically. If a UI library wants to run a shell command on install, stop. - Assess responsiveness and governance. Skim the issue tracker and recent pull requests. Are security reports triaged quickly? Is there a
SECURITY.mdwith a disclosure policy? Well-governed projects publish one.
Turning the checklist into a score
Consistency matters more than perfection. I score each dependency 0–5 on six criteria and require a weighted total above a threshold before adoption. Anything that fails a hard gate (malicious install script, incompatible license, unpatched critical CVE) is rejected outright no matter the score.
A Worked Example: Auditing Two Candidate Libraries
Say you need a rich-text editor for a customer-facing SaaS app. You have shortlisted two open-source candidates. Rather than pick by GitHub stars, you run both through the same rubric.
Candidate A has 28,000 stars, but its last release was 14 months ago, 96% of commits come from one person, and npm audit reports 3 high-severity vulnerabilities with no available fix. It pulls in 142 transitive dependencies.
Candidate B has 9,400 stars, ships a release roughly every three weeks, has five active maintainers, a published SECURITY.md, zero known high-severity CVEs, and 38 transitive dependencies.
| Criterion (weight) | Candidate A | Candidate B |
|---|---|---|
| Maintenance recency (x2) | 1 | 5 |
| Bus factor (x2) | 1 | 4 |
| Known CVEs (x3) | 0 | 5 |
| Dependency footprint (x1) | 1 | 4 |
| License fit — MIT both (x2) | 5 | 5 |
| Governance / docs (x1) | 2 | 5 |
| Weighted total (out of 55) | 15 | 50 |
Candidate A had triple the stars and lost decisively. The three unpatched high-severity CVEs alone are a hard gate. This is the entire point of scoring: it strips away the halo effect that popularity creates and forces you to look at the numbers that predict pain.
Tools I Use to Audit Open-Source Software
You do not need an enterprise security platform to do this well. Here is the stack I lean on, from free to paid, and where each one earns its keep.
| Tool | Best for | Cost | Catches malicious code? |
|---|---|---|---|
npm audit / pip-audit | Fast known-CVE scan in your ecosystem | Free | No, known CVEs only |
| OSV-Scanner (Google) | Cross-ecosystem SBOM vulnerability scan | Free | Partial |
| Snyk | Continuous monitoring + license checks | Free tier / paid | Some, plus behavioral flags |
| Socket.dev | Supply-chain behavior (install scripts, network access) | Free tier / paid | Yes, strong here |
| Manual code review | Social-engineering and logic risk | Your time | Yes, if you read carefully |
Notice the pattern: automated tools are excellent at known vulnerabilities and weak at novel malicious behavior. That is why the last row still matters. Socket.dev in particular is worth adding because it flags packages that suddenly start making network requests or shelling out during install, which is exactly the behavior that would have caught several recent npm supply-chain attacks earlier.
A minimal command-line workflow
- Install into a throwaway directory:
mkdir audit && cd audit && npm init -y. - Add the package with scripts ignored:
npm install <package> --ignore-scripts. - Run
npm audit --jsonand record severity counts. - Generate the tree:
npm ls --all > tree.txt. - Run
osv-scanner --lockfile=package-lock.json. - Open
node_modules/<package>/package.jsonand read every entry underscripts.
The --ignore-scripts flag matters. It lets you inspect what the package wants to run before you ever let it run.
Auditing WordPress, Joomla, and CMS Plugins Specifically
CMS plugins deserve their own attention because they run with high privileges inside your site and update on their own schedules. A single abandoned plugin with a known SQL injection flaw can compromise an entire WordPress install.
When auditing a WordPress or Joomla extension, apply the same checklist but add three CMS-specific checks:
- Update frequency against core releases. A pl
Cover image: Innovate Maryland Emerging Technology Center by MDGovpics, licensed under BY 2.0 via Openverse.








