find-cache-dir 3.x dependency vulnerability
lorand-horvath opened this issue · comments
There's a transient dependency vulnerability in semver 6 > make-dir 3 >find-cache-dir 3 > @vuetify/loader-shared as shown below, following creation of a new project with npm create vuetify@latest
semver <7.5.2
Severity: moderate
semver vulnerable to Regular Expression Denial of Service - https://github.com/advisories/GHSA-c2qf-rxjj-qqgw
fix available via `npm audit fix --force`
Will install vuetify@2.6.15, which is a breaking change
node_modules/make-dir/node_modules/semver
make-dir 2.0.0 - 3.1.0
Depends on vulnerable versions of semver
node_modules/make-dir
find-cache-dir 2.1.0 - 3.3.2
Depends on vulnerable versions of make-dir
node_modules/find-cache-dir
@vuetify/loader-shared >=1.1.3
Depends on vulnerable versions of find-cache-dir
Depends on vulnerable versions of vuetify
node_modules/@vuetify/loader-shared
vite-plugin-vuetify *
Depends on vulnerable versions of @vuetify/loader-shared
Depends on vulnerable versions of vuetify
node_modules/vite-plugin-vuetify
vuetify >=3.0.0-alpha.0
Depends on vulnerable versions of vite-plugin-vuetify
node_modules/vuetify
This can be fixed by bumping to find-cache-dir@4
Edit: Temporary solution via npm overrides in package.json
"overrides": {
"@vuetify/loader-shared": {
"find-cache-dir": "^4.0.0"
}
}
@lorand-horvath, thanks for sharing the temporary override.
When I override using find-cache-dir ^4.0.0, I get an error when attempting npm run serve
and npm run build
because find-cache-dir v4 is now published only as ES module: https://github.com/sindresorhus/find-cache-dir/releases/tag/v4.0.0
\node_modules\@vuetify\loader-shared\dist\styles\writeStyles.js:5
const findCacheDir = require("find-cache-dir");
^
Error [ERR_REQUIRE_ESM]: require() of ES Module \node_modules\find-cache-dir\index.js from \node_modules\@vuetify\loader-shared\dist\styles\writeStyles.js not supported.
Instead change the require of index.js in \node_modules\@vuetify\loader-shared\dist\styles\writeStyles.js to a dynamic import() which is available in all CommonJS modules.
Node.js v18.16.1
Temporary fix: modify @vuetify\loader-shared\dist\styles\writeStyles.js
line 5...
from:
const findCacheDir = require("find-cache-dir");
to:
const findCacheDir = (...args) => import("find-cache-dir").then(({ default: f }) => f(...args));
@ctrueblood-epri Thanks for the input, you are 100% right, find-cache-dir@4.0.0
is indeed an ESM-only release and adjustments need to be made to convert CommonJS require() to ESM import.
@KaelWD @nekosaur @johnleider I'd very much like to hear your input on #309 and would like to know if changes similar to what @ctrueblood-epri made above are required, or perhaps there's a better (cleaner) way of importing ESM-only modules in this project?
https://overreacted.io/npm-audit-broken-by-design/
There is no vulnerability, make-dir has a hardcoded range: https://github.com/sindresorhus/make-dir/blob/main/index.js#L7
Even if it was possible to exploit this somehow, the worst thing a ReDoS can do here is crash vite.
@KaelWD I'm aware of Abramov's article since it was published and I understand that the so called vulnerabilities are a non-issue for packages used only in development, such as vite-plugin-vuetify
.
I also get that running npm audit --production
hides the dev vulnerabilities, which is neat and all.
But that's not what I was asking. My problem is with the way developers such as @sindresorhus have long ago switched to ESM-only packages, basically forcing it down on us and what can be done to still somehow integrate such a package into code that uses require() instead of import, as is the case here with require('find-cache-dir')
. Updating to find-cache-dir@4
would seemingly solve any vuln reports and I don't see any negative implications if it were to be done. Can it be done? Is the code above the way to properly do it? Can we use await import()
? Or let's just forget about it and don't use ESM-only packages, because it's difficult and messy?
Also, I'm trying to think from a beginner's point of view - it must be quite discouraging to see vulnerabilities galore reported as soon as Vuetify is installed...
Can we use await import()?
Yes, I would have to increase the node requirement to 14 though. The cacheDir
initialisation would also have to be made async in writeStyles
.
I'm trying to think from a beginner's point of view - it must be quite discouraging to see vulnerabilities galore
That's a larger problem with NPM itself, this one change won't even make a dent.
@KaelWD Requiring Node 14 is fine by me. Vite requires at least 16, in a way, at least when deploying to Namecheap, because rollup 3.x needs at least npm 8 to run properly.
Namecheap only has node14 with the default npm 6 available on their servers (CentOS 6! still).
Edit: Obviously, I don't build with Vite on the hosting server :-)
@lorand-horvath, thanks for sharing the temporary override.
When I override using find-cache-dir ^4.0.0, I get an error when attempting
npm run serve
andnpm run build
because find-cache-dir v4 is now published only as ES module: https://github.com/sindresorhus/find-cache-dir/releases/tag/v4.0.0\node_modules\@vuetify\loader-shared\dist\styles\writeStyles.js:5 const findCacheDir = require("find-cache-dir"); ^ Error [ERR_REQUIRE_ESM]: require() of ES Module \node_modules\find-cache-dir\index.js from \node_modules\@vuetify\loader-shared\dist\styles\writeStyles.js not supported. Instead change the require of index.js in \node_modules\@vuetify\loader-shared\dist\styles\writeStyles.js to a dynamic import() which is available in all CommonJS modules. Node.js v18.16.1
Temporary fix: modify
@vuetify\loader-shared\dist\styles\writeStyles.js
line 5...from:
const findCacheDir = require("find-cache-dir");to:
const findCacheDir = (...args) => import("find-cache-dir").then(({ default: f }) => f(...args));
Thanks for the information all. I am also working through this issue as need to replace semver versions below 7.5.2 due to the "vulnerability".
Here is another package.json npm override workaround that I've tried that doesn't require any CommonJS to ESM import conversion (the above suggestion did not work for me in my application):
"overrides": {
"find-cache-dir@3.3.2": {
"make-dir": "^4.0.0"
}
}
find-cache-dir can stay on 3.3.2 but utilise make-dir 4.0.0 which has since replaced the semver 6.x vulnerable version with the latest and non-vulnerable versions that are >7.5.2. And make-dir 4.0.0 is in the CommonJS format.
Update: semver 6.3.1 was released on July 10, which addressed the vulnerability:
https://github.com/npm/node-semver/releases
The advisory now recognizes semver 6.3.1 as a patched version:
GHSA-c2qf-rxjj-qqgw
I removed temporary overrides, updated the package, and see 0 vulnerabilities.