Socket
Socket
Sign inDemoInstall

is-my-node-vulnerable

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

is-my-node-vulnerable - npm Package Compare versions

Comparing version 1.0.0-2 to 1.0.0-4

.github/workflows/test.yml

16

ascii.js

@@ -1,2 +0,2 @@

const clc = require('cli-color');
const clc = require('cli-color')

@@ -11,3 +11,3 @@ const danger = `

`;
`

@@ -22,9 +22,9 @@ const allGood = `

`;
`
const bold = clc.bold;
const bold = clc.bold
const vulnerableWarning = bold(`The current Node.js version (${process.version}) is vulnerable to the following CVEs:`);
const vulnerableWarning = bold(`The current Node.js version (${process.version}) is vulnerable to the following CVEs:`)
const separator = '='.repeat(process.stdout.columns);
const separator = '='.repeat(process.stdout.columns)

@@ -36,3 +36,3 @@ module.exports = {

vulnerableWarning,
separator,
};
separator
}
#!/usr/bin/env node
const { request, stream, setGlobalDispatcher, Agent } = require('undici');
const EE = require('node:events');
const fs = require('node:fs');
const path = require('node:path');
const debug = require('debug')('is-my-node-vulnerable');
const satisfies = require('semver/functions/satisfies');
const { danger, vulnerableWarning, bold, separator, allGood } = require('./ascii');
const { request, stream, setGlobalDispatcher, Agent } = require('undici')
const EE = require('node:events')
const fs = require('node:fs')
const path = require('node:path')
const debug = require('debug')('is-my-node-vulnerable')
const satisfies = require('semver/functions/satisfies')
const { danger, vulnerableWarning, bold, separator, allGood } = require('./ascii')
setGlobalDispatcher(new Agent({ connections: 20 }));
setGlobalDispatcher(new Agent({ connections: 20 }))
const CORE_RAW_URL = 'https://raw.githubusercontent.com/nodejs/security-wg/main/vuln/core/index.json'
let lastETagValue;
let lastETagValue
const coreLocalFile = path.join(__dirname, 'core.json');
const ETagFile = path.join(__dirname, '.etag');
const coreLocalFile = path.join(__dirname, 'core.json')
const ETagFile = path.join(__dirname, '.etag')
async function readLocal(file) {
return require(file);
async function readLocal (file) {
return require(file)
}
function loadETag() {
function loadETag () {
if (fs.existsSync(ETagFile)) {
lastETagValue = fs.readFileSync(ETagFile).toString();
debug('Loading local ETag')
lastETagValue = fs.readFileSync(ETagFile).toString()
}
}
function updateLastETag(etag) {
lastETagValue = etag;
fs.writeFileSync(ETagFile, lastETagValue);
function updateLastETag (etag) {
lastETagValue = etag
fs.writeFileSync(ETagFile, lastETagValue)
}
async function fetchCoreIndex() {
const abortRequest = new EE();
async function fetchCoreIndex () {
const abortRequest = new EE()
await stream(CORE_RAW_URL, { signal: abortRequest }, ({ statusCode }) => {
if (statusCode !== 200) {
console.error('Request to Github failed. Aborting...');
abortRequest.emit('abort');
process.nextTick(() => { process.exit(1); });
console.error('Request to Github failed. Aborting...')
abortRequest.emit('abort')
process.nextTick(() => { process.exit(1) })
}
return fs.createWriteStream(coreLocalFile);
});
return readLocal(coreLocalFile);
return fs.createWriteStream(coreLocalFile, { flags: 'w', autoClose: true })
})
return readLocal(coreLocalFile)
}
async function getCoreIndex() {
const { headers } = await request(CORE_RAW_URL, { method: 'HEAD' });
if (!lastETagValue || lastETagValue !== headers['etag']) {
updateLastETag(headers['etag']);
debug('Creating local core.json');
return fetchCoreIndex();
async function getCoreIndex () {
const { headers } = await request(CORE_RAW_URL, { method: 'HEAD' })
if (!lastETagValue || lastETagValue !== headers.etag || !fs.existsSync(coreLocalFile)) {
updateLastETag(headers.etag)
debug('Creating local core.json')
return fetchCoreIndex()
} else {
debug('No updates from upstream. Getting a cached version.');
return readLocal(coreLocalFile);
debug(`No updates from upstream. Getting a cached version: ${coreLocalFile}`)
return readLocal(coreLocalFile)
}
}
function getVulnerabilityList(data) {
const list = [];
function getVulnerabilityList (currentVersion, data) {
const list = []
for (const key in data) {
const vuln = data[key];
const vuln = data[key]
if (
satisfies(process.version, vuln.vulnerable) &&
!satisfies(process.version, vuln.patched)
satisfies(currentVersion, vuln.vulnerable) &&
!satisfies(currentVersion, vuln.patched)
) {

@@ -71,19 +72,36 @@ list.push(`${bold(vuln.cve)}: ${vuln.overview}\n${bold('Patched versions')}: ${vuln.patched}`)

}
return list;
return list
}
async function main() {
loadETag();
const coreIndex = await getCoreIndex();
const list = getVulnerabilityList(coreIndex);
async function main (currentVersion) {
const coreIndex = await getCoreIndex()
const list = getVulnerabilityList(currentVersion, coreIndex)
if (list.length) {
console.error(danger);
console.error(vulnerableWarning + '\n');
console.error(`${list.join(`\n${separator}\n\n`)}\n${separator}`);
process.exit(1);
console.error(danger)
console.error(vulnerableWarning + '\n')
console.error(`${list.join(`\n${separator}\n\n`)}\n${separator}`)
process.exit(1)
} else {
console.info(allGood);
console.info(allGood)
}
}
main();
async function isNodeVulnerable (version) {
const coreIndex = await getCoreIndex()
const list = getVulnerabilityList(version, coreIndex)
return list.length > 0
}
if (process.argv[2] !== '-r') {
loadETag()
}
// CLI
if (require.main === module) {
console.log('calling from main')
main(process.version)
} else {
module.exports = {
isNodeVulnerable
}
}
{
"name": "is-my-node-vulnerable",
"version": "1.0.0-2",
"version": "1.0.0-4",
"description": "package that checks if your Node.js installation is vulnerable to known security vulnerabilities",

@@ -14,3 +14,4 @@ "main": "index.js",

"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "npm run lint && node test.js",
"lint": "standard"
},

@@ -24,3 +25,6 @@ "author": "RafaelGSS <rafael.nunu@hotmail.com>",

"undici": "^5.15.1"
},
"devDependencies": {
"standard": "^17.0.0"
}
}
# is-my-node-vulnerable
This package helps ensure the security of your Node.js installation by checking for known vulnerabilities.
It compares the version of Node.js you have installed (`process.version`) to the [Node.js Security Database][]
and alerts you if a vulnerability is found.
## Usage
```
npx is-my-node-vulnerable
```
It's strongly recommended to include this as a step in the app CI.
### Output - When vulnerable
```console
$ node -v
v19.0.0
$ npx is-my-node-vulnerable
██████ █████ ███ ██ ██████ ███████ ██████
██ ██ ██ ██ ████ ██ ██ ██ ██ ██
██ ██ ███████ ██ ██ ██ ██ ███ █████ ██████
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██████ ██ ██ ██ ████ ██████ ███████ ██ ██
The current Node.js version (v19.0.0) is vulnerable to the following CVEs:
CVE-2022-43548: The Node.js rebinding protector for --inspect still allows invalid IP address, specifically, the octal format.
Patched versions: ^14.21.1 || ^16.18.1 || ^18.12.1 || ^19.0.1
=============================================================================================================================================
```
### Output - When non-vulnerable
```console
$ node -v
v19.5.0
$ npx is-my-node-vulnerable
█████ ██ ██ ██████ ██████ ██████ ██████ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
███████ ██ ██ ██ ███ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ███████ ███████ ██████ ██████ ██████ ██████ ██
```
## API
This package also exports a function `isNodeVulnerable` to perform the check in runtime
```js
const { isNodeVulnerable } = require('is-my-node-vulnerable')
isNodeVulnerable('19.0.0') // true
```
[Node.js Security Database]: https://github.com/nodejs/security-wg/tree/main/vuln
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc