Skip to content

fix(npm): the dev-build fallback resolves into node_modules/target, which a third party can own #1097

Description

@BryanFRD

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions