Vulnerability Detection Using OSV.dev (Terminal-Only Approach)

17 / Apr / 2026 by Amit Kumar 0 comments

Introduction

Modern JavaScript applications—especially React Native—depend on hundreds of npm packages. The real risk isn’t just outdated packages, but hidden vulnerabilities inside your dependency tree.

Traditional tools like npm audit often overwhelm developers with noisy output and low-context alerts. What we actually need is:

  • Accurate vulnerability detection
  • Minimal noise
  • Actionable output

This is where OSV.dev (Open Source Vulnerabilities) comes in.

 Why OSV.dev?

OSV.dev provides a unified vulnerability database that aggregates data from multiple ecosystems and security sources.

Unlike traditional tools:

  • It focuses on real known vulnerabilities
  • It supports precise version matching
  • It reduces false positives

It has already flagged multiple malicious npm packages like:

  • react-native-website → malicious code injected
  • react-native-latest → executes suspicious commands
  • react-native-show-message-extension → compromised package

This proves one thing: you cannot trust dependencies blindly anymore.

How Vulnerability Detection Works

The process is simple but powerful:

  1. Read all installed dependencies
  2. Extract exact versions (not ranges)
  3. Send them to OSV.dev API
  4. Check if vulnerabilities exist
  5. Show ONLY affected packages

Step 1: Read Installed Packages

We extract dependencies directly from:

  • package.json
  • node_modules (for exact installed version)

 readPackages.js

const fs = require("fs");
const path = require("path");

function getInstalledPackages(projectRoot) {
const pkgPath = path.join(projectRoot, "package.json");
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));

const allDeps = {
...pkg.dependencies,
...pkg.devDependencies,
};

const result = [];

for (const dep of Object.keys(allDeps)) {
try {
const depPkgPath = path.join(
projectRoot,
"node_modules",
dep,
"package.json"
);

if (fs.existsSync(depPkgPath)) {
const depPkg = JSON.parse(fs.readFileSync(depPkgPath, "utf8"));

result.push({
name: dep,
version: depPkg.version,
});
}
} catch (err) {
// ignore broken deps
}
}

return result;
}

module.exports = { getInstalledPackages };

Step 2: Check Vulnerabilities via OSV

We call OSV’s batch API:

https://api.osv.dev/v1/querybatch

This allows us to check multiple packages at once.

 osvSecurity.js

const OSV_API = "https://api.osv.dev/v1/querybatch";

async function checkVulnerabilities(packages) {
const queries = packages.map((pkg) => ({
package: {
name: pkg.name,
ecosystem: "npm",
},
version: pkg.version,
}));

const response = await fetch(OSV_API, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ queries }),
});

const data = await response.json();

const vulnerablePackages = [];

data.results.forEach((result, index) => {
if (result.vulns && result.vulns.length > 0) {
vulnerablePackages.push({
name: packages[index].name,
version: packages[index].version,
vulnerabilities: result.vulns.map((v) => ({
id: v.id,
summary: v.summary,
severity: v.severity || "UNKNOWN",
})),
});
}
});

return vulnerablePackages;
}

module.exports = { checkVulnerabilities };

📄 checkVulnerabilities.js (FINAL SCRIPT)

#!/usr/bin/env node

const path = require("path");
const { getInstalledPackages } = require("./readPackages");
const { checkVulnerabilities } = require("./osvSecurity");

const PROJECT_ROOT = process.cwd();

async function run() {
console.log("🔍 Scanning for vulnerabilities...\n");

const packages = getInstalledPackages(PROJECT_ROOT);

if (!packages.length) {
console.log("No packages found.");
return;
}

const vulnerable = await checkVulnerabilities(packages);

if (!vulnerable.length) {
console.log("✅ No vulnerabilities found.");
return;
}

console.log("🚨 Vulnerable Packages Found:\n");

vulnerable.forEach((pkg) => {
console.log(`📦 ${pkg.name}@${pkg.version}`);

pkg.vulnerabilities.forEach((vuln) => {
console.log(` ⚠️ ${vuln.id}`);
console.log(` 📝 ${vuln.summary || "No description"}`);
console.log(` 🔥 Severity: ${vuln.severity}`);
console.log("");
});
});
}

run().catch((err) => {
console.error("Error:", err.message);
});

How to Run

Install dependency:

npm install node-fetch

Run:

node checkVulnerabilities.js

Sample Output

🔍 Scanning for vulnerabilities…

🚨 Vulnerable Packages Found:

📦 lodash@4.17.15
⚠️ GHSA-xxxx
📝 Prototype Pollution vulnerability
🔥 Severity: HIGH

📦 minimist@0.0.8
⚠️ GHSA-yyyy
📝 Arbitrary code execution issue
🔥 Severity: CRITICAL

 

vulnerablePackages

vulnerablePackages

Final Thought

Dependency security is no longer optional.

With real-world incidents of malicious npm packages and even critical RCE vulnerabilities in widely used tools, relying on blind trust is risky.

A simple terminal-based vulnerability scanner like this gives you:

  • Immediate visibility
  • Zero noise
  • Real security insights

If it’s not secure, it should be visible instantly.

FOUND THIS USEFUL? SHARE IT

Leave a Reply

Your email address will not be published. Required fields are marked *