The npm wrapper's dev-build fallback points outside the installed package, into a directory a third party can own. Fixed in #1096, filed here for the record.
The path
npm/bin/ferrflow.js falls back to a local Cargo build when the platform package is not resolvable:
const devBuild = join(__dirname, "..", "..", "target", "release", `ferrflow${ext}`);
From a source checkout that is <repo>/target/release/, which is the intent. Installed from npm, __dirname is node_modules/ferrflow/bin and the same expression becomes:
node_modules/target/release/ferrflow
which belongs to any package installing as target. target exists on npm at 0.0.2 and ships nothing at that path today.
Reproduced on 7.21.5
$ npm install ferrflow@7.21.5 --omit=optional
$ cp <any binary> node_modules/target/release/ferrflow.exe
$ npx ferrflow --version
ferrflow 7.11.1
A supported platform, the real binary merely absent, and the wrapper ran something else.
Reachability
--omit=optional is the blunt way in, but not the only one. Optional dependency failures are silent by design, so a network blip during npm install leaves the platform package missing and the wrapper looking at node_modules/target/.
What makes it worth a fix rather than a note: this package has no install scripts, and that is a property people audit for. The fallback quietly spends it. A hostile package needs no postinstall here, only a file at release/ferrflow and a user who eventually runs ferrflow.
Severity is still low. It needs a package named target in the dependency tree, and whoever can arrange that usually has easier routes. It is a case that should not have been reachable at all.
Fix
#1096 gates the fallback on Cargo.toml sitting next to target/, which is true in a checkout and impossible under node_modules: npm unpacks files under node_modules/<name>/, so nothing can create node_modules/Cargo.toml, and that name is not a legal package name in any case.
Verified in both directions, details in the pull request.
How it came up
A dependency scanner flagged npm/bin/ferrflow.js and scripts/validate-site-docs.mjs for shell access on 7.21.5. Both were false alarms: the wrapper spawns with an argv array and no shell: true, and the docs script has no child_process at all, its only exec calls being RegExp.exec. It is also not published; the npm tarball is four files. The real finding was one line below what the scanner was pointing at.
The npm wrapper's dev-build fallback points outside the installed package, into a directory a third party can own. Fixed in #1096, filed here for the record.
The path
npm/bin/ferrflow.jsfalls back to a local Cargo build when the platform package is not resolvable:From a source checkout that is
<repo>/target/release/, which is the intent. Installed from npm,__dirnameisnode_modules/ferrflow/binand the same expression becomes:which belongs to any package installing as
target.targetexists on npm at 0.0.2 and ships nothing at that path today.Reproduced on 7.21.5
A supported platform, the real binary merely absent, and the wrapper ran something else.
Reachability
--omit=optionalis the blunt way in, but not the only one. Optional dependency failures are silent by design, so a network blip duringnpm installleaves the platform package missing and the wrapper looking atnode_modules/target/.What makes it worth a fix rather than a note: this package has no install scripts, and that is a property people audit for. The fallback quietly spends it. A hostile package needs no
postinstallhere, only a file atrelease/ferrflowand a user who eventually runsferrflow.Severity is still low. It needs a package named
targetin the dependency tree, and whoever can arrange that usually has easier routes. It is a case that should not have been reachable at all.Fix
#1096 gates the fallback on
Cargo.tomlsitting next totarget/, which is true in a checkout and impossible undernode_modules: npm unpacks files undernode_modules/<name>/, so nothing can createnode_modules/Cargo.toml, and that name is not a legal package name in any case.Verified in both directions, details in the pull request.
How it came up
A dependency scanner flagged
npm/bin/ferrflow.jsandscripts/validate-site-docs.mjsfor shell access on 7.21.5. Both were false alarms: the wrapper spawns with an argv array and noshell: true, and the docs script has nochild_processat all, its onlyexeccalls beingRegExp.exec. It is also not published; the npm tarball is four files. The real finding was one line below what the scanner was pointing at.