I got some vulnerabilities resolved in my Node.js project by forcing some nested dependency updates but I need help understanding what's actually happening behind the scene of this improvement.
Here is my original "package.json"
{
"name": "my-app",
"private": true,
"version": "3.9.5",
"description": "my application",
"keywords": [],
"dependencies": {
"@sailshq/connect-redis": "^3.2.1",
"@sailshq/lodash": "^3.10.3",
"@sailshq/socket.io-redis": "^5.2.0",
"axios": "^0.21.1",
"csv": "^6.0.1",
"csv-stringify": "^6.0.1",
"events": "^3.1.0",
"form-data": "^4.0.0",
"grunt": "1.4.1",
"health-check": "1.0.3",
"kafka-node": "^5.0.0",
"moment": "^2.26.0",
"passport": "^0.4.1",
"passport-oauth2": "^1.5.0",
"sails": "^1.2.4",
"sails-hook-grunt": "^5.0.0",
"sails-hook-orm": "^2.1.1",
"sails-hook-sockets": "^2.0.1",
"sails-hook-uploads": "^0.4.3",
"sails-mongo": "^2.0.0",
"sails-redis": "^1.0.0",
"my-inhouse-logger": "3.8.2",
"url-pattern": "^1.0.3"
},
"devDependencies": {
"eslint": "5.16.0",
"jest": "^24.9.0",
"supertest": "^4.0.2"
},
"scripts": {
"start": "NODE_ENV=production node app.js",
"start:dev": "NODE_ENV=dev sails lift",
"start-win": "sails lift",
"test": "NODE_ENV=test jest -c jest.config.js",
"test:coverage": "npm run test -- --coverage",
"test:watch": "npm run test -- --watch",
"test:all": "npm run lint && npm run test:coverage",
"lint": "./node_modules/eslint/bin/eslint.js . --max-warnings=0 --report-unused-disable-directives && echo '✔ Your .js files look good.'",
"jest": "NODE_ENV=test jest -c jest.config.js",
"jest-coverage": "NODE_ENV=test jest -c jest.config.js --coverage --runInBand",
"jest-no-coverage": "NODE_ENV=test jest -c jest.config.js --runInBand",
"jest-functional": "NODE_ENV=test jest -c jest.config.functional.js --runInBand",
"clean": "/bin/bash -c 'rm assets/js/* assets/css/* assets/fonts/* assets/index.html'",
"custom-tests": "echo \"(No other custom tests yet.)\" && echo"
},
"main": "app.js",
"repository": {
"type": "git",
"url": "git://github.com/myprofile/nbackend.git"
},
"author": "my name",
"license": "",
"engines": {
"node": "^16.14"
}
}
When I did "npm install" and then "npm audit", I got
32 vulnerabilities (5 low, 8 moderate, 9 high, 10 critical)
Here is the full report
~/ideaprojects/myapp/backend$ npm audit --registry=https://registry.npmjs.org
# npm audit report
acorn 5.5.0 - 5.7.3
Severity: high
Regular Expression Denial of Service in Acorn - https://github.com/advisories/GHSA-6chw-6frg-f759
fix available via `npm audit fix`
node_modules/sails-hook-grunt/node_modules/acorn
ajv <6.12.3
Severity: moderate
Prototype Pollution in Ajv - https://github.com/advisories/GHSA-v88g-cgmw-v5xw
fix available via `npm audit fix`
node_modules/sails-hook-grunt/node_modules/ajv
node_modules/sails-hook-grunt/node_modules/eslint/node_modules/ajv
eslint 4.2.0 - 5.0.0-rc.0
Depends on vulnerable versions of ajv
node_modules/sails-hook-grunt/node_modules/eslint
ansi-regex 3.0.0
Severity: moderate
Inefficient Regular Expression Complexity in chalk/ansi-regex - https://github.com/advisories/GHSA-93q8-gq69-wqmw
fix available via `npm audit fix`
node_modules/sails-hook-grunt/node_modules/eslint/node_modules/ansi-regex
node_modules/sails-hook-grunt/node_modules/inquirer/node_modules/ansi-regex
node_modules/sails-hook-grunt/node_modules/string-width/node_modules/ansi-regex
debug <2.6.9
Regular Expression Denial of Service in debug - https://github.com/advisories/GHSA-gxpj-cx7g-858c
fix available via `npm audit fix`
node_modules/sails-hook-grunt/node_modules/mocha/node_modules/debug
mocha 0.6.0 - 6.2.2 || 7.0.0-esm1 - 7.1.0
Depends on vulnerable versions of debug
Depends on vulnerable versions of diff
Depends on vulnerable versions of growl
Depends on vulnerable versions of mkdirp
node_modules/sails-hook-grunt/node_modules/mocha
diff <3.5.0
Severity: high
Regular Expression Denial of Service (ReDoS) - https://github.com/advisories/GHSA-h6ch-v84p-w6p9
fix available via `npm audit fix`
node_modules/sails-hook-grunt/node_modules/diff
mocha 0.6.0 - 6.2.2 || 7.0.0-esm1 - 7.1.0
Depends on vulnerable versions of debug
Depends on vulnerable versions of diff
Depends on vulnerable versions of growl
Depends on vulnerable versions of mkdirp
node_modules/sails-hook-grunt/node_modules/mocha
engine.io <4.0.0
Severity: high
Resource exhaustion in engine.io - https://github.com/advisories/GHSA-j4f2-536g-r55m
fix available via `npm audit fix --force`
Will install [email protected], which is a breaking change
node_modules/engine.io
socket.io 1.0.0-pre - 2.4.1
Depends on vulnerable versions of engine.io
node_modules/socket.io
sails-hook-sockets *
Depends on vulnerable versions of machinepack-redis
Depends on vulnerable versions of socket.io
node_modules/sails-hook-sockets
getobject 0.1.0
Severity: critical
Prototype pollution vulnerability in 'getobject' - https://github.com/advisories/GHSA-957j-59c2-j692
No fix available
node_modules/sails-hook-grunt/node_modules/getobject
grunt-legacy-util <=2.0.0
Depends on vulnerable versions of getobject
node_modules/sails-hook-grunt/node_modules/grunt-legacy-util
grunt <=1.2.1
Depends on vulnerable versions of grunt-legacy-util
node_modules/sails-hook-grunt/node_modules/grunt
sails-hook-grunt *
Depends on vulnerable versions of grunt
node_modules/sails-hook-grunt
growl <1.10.0
Severity: critical
Command Injection in growl - https://github.com/advisories/GHSA-qh2h-chj9-jffq
fix available via `npm audit fix`
node_modules/sails-hook-grunt/node_modules/growl
mocha 0.6.0 - 6.2.2 || 7.0.0-esm1 - 7.1.0
Depends on vulnerable versions of debug
Depends on vulnerable versions of diff
Depends on vulnerable versions of growl
Depends on vulnerable versions of mkdirp
node_modules/sails-hook-grunt/node_modules/mocha
grunt <=1.2.1
Severity: critical
Arbitrary Code Execution in grunt - https://github.com/advisories/GHSA-m5pj-vjjf-4m3h
Depends on vulnerable versions of grunt-legacy-util
No fix available
node_modules/sails-hook-grunt/node_modules/grunt
sails-hook-grunt *
Depends on vulnerable versions of grunt
node_modules/sails-hook-grunt
hosted-git-info <2.8.9
Severity: moderate
Regular Expression Denial of Service in hosted-git-info - https://github.com/advisories/GHSA-43f8-2h32-f4cj
fix available via `npm audit fix`
node_modules/sails-hook-grunt/node_modules/hosted-git-info
json-schema <0.4.0
Severity: moderate
json-schema is vulnerable to Prototype Pollution - https://github.com/advisories/GHSA-896r-f27r-55mw
fix available via `npm audit fix`
node_modules/sails-hook-grunt/node_modules/json-schema
jsprim 0.3.0 - 1.4.1 || 2.0.0 - 2.0.1
Depends on vulnerable versions of json-schema
node_modules/sails-hook-grunt/node_modules/jsprim
lodash <=4.17.20
Severity: critical
Prototype Pollution in lodash - https://github.com/advisories/GHSA-p6mc-m468-83gw
Command Injection in lodash - https://github.com/advisories/GHSA-35jh-r3h4-6jhm
Prototype Pollution in lodash - https://github.com/advisories/GHSA-jf85-cpcp-j695
fix available via `npm audit fix`
node_modules/sails-hook-grunt/node_modules/lodash
minimist <=1.2.5
Severity: critical
Prototype Pollution in minimist - https://github.com/advisories/GHSA-xvch-5gv4-984h
Prototype Pollution in minimist - https://github.com/advisories/GHSA-vh95-rmgr-6w4m
Prototype Pollution in minimist - https://github.com/advisories/GHSA-vh95-rmgr-6w4m
fix available via `npm audit fix`
node_modules/sails-hook-grunt/node_modules/minimist
node_modules/sails-hook-grunt/node_modules/mkdirp/node_modules/minimist
mkdirp 0.4.1 - 0.5.1
Depends on vulnerable versions of minimist
node_modules/@sailshq/nedb/node_modules/mkdirp
node_modules/sails-hook-grunt/node_modules/mkdirp
@sailshq/nedb *
Depends on vulnerable versions of mkdirp
node_modules/@sailshq/nedb
sails-disk >=2.1.1
Depends on vulnerable versions of @sailshq/nedb
node_modules/sails-disk
mocha 0.6.0 - 6.2.2 || 7.0.0-esm1 - 7.1.0
Depends on vulnerable versions of debug
Depends on vulnerable versions of diff
Depends on vulnerable versions of growl
Depends on vulnerable versions of mkdirp
node_modules/sails-hook-grunt/node_modules/mocha
path-parse <1.0.7
Severity: moderate
Regular Expression Denial of Service in path-parse - https://github.com/advisories/GHSA-hj48-42vr-x3v9
fix available via `npm audit fix`
node_modules/sails-hook-grunt/node_modules/path-parse
redis 2.6.0 - 3.1.0
Potential exponential regex in monitor mode - https://github.com/advisories/GHSA-35q2-47q7-3pc3
fix available via `npm audit fix --force`
Will install [email protected], which is a breaking change
node_modules/redis
node_modules/sails-redis/node_modules/redis
@sailshq/socket.io-redis *
Depends on vulnerable versions of redis
node_modules/@sailshq/socket.io-redis
machinepack-redis >=1.1.1
Depends on vulnerable versions of redis
node_modules/machinepack-redis
node_modules/sails-redis/node_modules/machinepack-redis
sails *
Depends on vulnerable versions of machinepack-redis
node_modules/sails
sails-hook-sockets *
Depends on vulnerable versions of machinepack-redis
Depends on vulnerable versions of socket.io
node_modules/sails-hook-sockets
sails-redis >=1.0.0-0
Depends on vulnerable versions of machinepack-redis
node_modules/sails-redis
sails *
Severity: moderate
Prototype Pollution in Sails.js - https://github.com/advisories/GHSA-8v3j-jfg3-v3fv
Depends on vulnerable versions of machinepack-redis
No fix available
node_modules/sails
trim-newlines <3.0.1
Severity: high
Regular Expression Denial of Service in trim-newlines - https://github.com/advisories/GHSA-7p7h-4mm5-852v
fix available via `npm audit fix`
node_modules/sails-hook-grunt/node_modules/trim-newlines
meow 3.4.0 - 5.0.0
Depends on vulnerable versions of trim-newlines
node_modules/meow
node_modules/sails-hook-grunt/node_modules/meow
websocket-extensions <0.1.4
Severity: high
Regular Expression Denial of Service in websocket-extensions (NPM package) - https://github.com/advisories/GHSA-g78m-2chm-r7qv
fix available via `npm audit fix`
node_modules/sails-hook-grunt/node_modules/websocket-extensions
32 vulnerabilities (5 low, 8 moderate, 9 high, 10 critical)
To address issues that do not require attention, run:
npm audit fix
To address all issues possible (including breaking changes), run:
npm audit fix --force
Some issues need review, and may require choosing
a different dependency.
I added an "overrides" section to "package.json" to force some nested dependency update and improve the vulnerability report. Here is the new "package.json"
{
"name": "my-app",
"private": true,
"version": "3.9.5",
"description": "my application",
"keywords": [],
"dependencies": {
"@sailshq/connect-redis": "^3.2.1",
"@sailshq/lodash": "^3.10.3",
"@sailshq/socket.io-redis": "^5.2.0",
"axios": "^0.21.1",
"csv": "^6.0.1",
"csv-stringify": "^6.0.1",
"events": "^3.1.0",
"form-data": "^4.0.0",
"grunt": "1.4.1",
"health-check": "1.0.3",
"kafka-node": "^5.0.0",
"moment": "^2.26.0",
"passport": "^0.4.1",
"passport-oauth2": "^1.5.0",
"sails": "^1.2.4",
"sails-hook-grunt": "^5.0.0",
"sails-hook-orm": "^2.1.1",
"sails-hook-sockets": "^2.0.1",
"sails-hook-uploads": "^0.4.3",
"sails-mongo": "^2.0.0",
"sails-redis": "^1.0.0",
"my-inhouse-logger": "3.8.2",
"url-pattern": "^1.0.3"
},
"devDependencies": {
"eslint": "5.16.0",
"jest": "^24.9.0",
"supertest": "^4.0.2"
},
"overrides": {
"grunt": "1.4.1",
"lodash": "4.17.21",
"sails-disk": "2.1.1",
"minimist": "1.2.6",
"node-notifier": "10.0.1",
"trim-newlines": "4.0.2",
"validator": "13.7.0",
"getobject": "1.0.2",
"grunt-legacy-util": "2.0.1"
},
"scripts": {
"start": "NODE_ENV=production node app.js",
"start:dev": "NODE_ENV=dev sails lift",
"start-win": "sails lift",
"test": "NODE_ENV=test jest -c jest.config.js",
"test:coverage": "npm run test -- --coverage",
"test:watch": "npm run test -- --watch",
"test:all": "npm run lint && npm run test:coverage",
"lint": "./node_modules/eslint/bin/eslint.js . --max-warnings=0 --report-unused-disable-directives && echo '✔ Your .js files look good.'",
"jest": "NODE_ENV=test jest -c jest.config.js",
"jest-coverage": "NODE_ENV=test jest -c jest.config.js --coverage --runInBand",
"jest-no-coverage": "NODE_ENV=test jest -c jest.config.js --runInBand",
"jest-functional": "NODE_ENV=test jest -c jest.config.functional.js --runInBand",
"clean": "/bin/bash -c 'rm assets/js/* assets/css/* assets/fonts/* assets/index.html'",
"custom-tests": "echo \"(No other custom tests yet.)\" && echo"
},
"main": "app.js",
"repository": {
"type": "git",
"url": "git://github.com/myprofile/nbackend.git"
},
"author": "my name",
"license": "",
"engines": {
"node": "^16.14"
}
}
But I still got the same vulnerability report.
Then in addition to "overrides" in "package.json", based on a suggestion on another question here on Stack Overflow, I also modified "package-lock.json" with just this block bellow that doesn't even look like a normal structure of what we usually have in "package-lock.json"
{
"dependencies": {
"sails-hook-grunt": {
"version": "5.0.0",
"from": "[email protected]",
"dependencies": {
"getobject": {
"version": "1.0.2",
"from": "[email protected]"
},
"grunt-legacy-util": {
"version": "2.0.1",
"from": "[email protected]"
}
}
}
}
}
Now if I run "npm install" and then "npm audit", I get a much better report like this
8 vulnerabilities (4 low, 1 moderate, 3 high)
Here is the full improved report
~/ideaprojects/myapp/backend$ npm audit --registry=https://registry.npmjs.org
# npm audit report
engine.io <4.0.0
Severity: high
Resource exhaustion in engine.io - https://github.com/advisories/GHSA-j4f2-536g-r55m
fix available via `npm audit fix --force`
Will install [email protected], which is a breaking change
node_modules/engine.io
socket.io 1.0.0-pre - 2.4.1
Depends on vulnerable versions of engine.io
node_modules/socket.io
sails-hook-sockets *
Depends on vulnerable versions of machinepack-redis
Depends on vulnerable versions of socket.io
node_modules/sails-hook-sockets
redis 2.6.0 - 3.1.0
Potential exponential regex in monitor mode - https://github.com/advisories/GHSA-35q2-47q7-3pc3
fix available via `npm audit fix --force`
Will install [email protected], which is a breaking change
node_modules/redis
node_modules/sails-redis/node_modules/redis
@sailshq/socket.io-redis *
Depends on vulnerable versions of redis
node_modules/@sailshq/socket.io-redis
machinepack-redis >=1.1.1
Depends on vulnerable versions of redis
node_modules/machinepack-redis
node_modules/sails-redis/node_modules/machinepack-redis
sails *
Depends on vulnerable versions of machinepack-redis
node_modules/sails
sails-hook-sockets *
Depends on vulnerable versions of machinepack-redis
Depends on vulnerable versions of socket.io
node_modules/sails-hook-sockets
sails-redis >=1.0.0-0
Depends on vulnerable versions of machinepack-redis
node_modules/sails-redis
sails *
Severity: moderate
Prototype Pollution in Sails.js - https://github.com/advisories/GHSA-8v3j-jfg3-v3fv
Depends on vulnerable versions of machinepack-redis
No fix available
node_modules/sails
8 vulnerabilities (4 low, 1 moderate, 3 high)
To address all issues possible (including breaking changes), run:
npm audit fix --force
Some issues need review, and may require choosing
a different dependency.
If I either remove the "overrides" section in "package.json" or not modify "package-lock.json" like I mentioned above I won't get the vulnerability report improved. Looks like I need both.
Even if I do "npm install" again, all the vulnerabilities will get back into the report. And I really don't understand why.
But the main confusion is: how that modification I made to "package-lock.json" helps with a better vulnerability report. I know "npm install" regenerates "package-lock.json" and what I added there should be lost. Does "npm install" consider the dependency I manually added to "package-lock.json" before regenerating it? And why this should matter when I have all the dependencies overridden in my "package.json".
Any help would be appriciated!
As the saying goes, "It's not the things that you don't know that get you into trouble. It's the things that you know for sure but that just ain't so.". In your case:
That just ain't true!
package-lock.json
is only generated if it doesn't exist or when changes are made to the actually installed packages. It's best to think of it as overridingpackage.json
most of the time and I think that's exactly what is happening in your case.That said, it might be enough to add the
overrides
section, deletepackage-lock.json
, and re-runnpm install
to have it be regenerated with, hopefully, the new overrides.