Skip to content

[RRFC] Improve experience and security around npx and scoped packages #323

Description

@dominykas

Motivation ("The Why")

  • Reduce the amount of typing (and therefore typos) when executing commands in scoped packages
  • Same, but for commonly used commands which do not match the package name
  • Improve resilience against spoofing (esp. in the light of the recent article about hijacked public names)

Some of those were requests/issues even with the old npx that didn't get much attention.

Despite reporting multiple issues in here, I figure they are all somewhat related and probably need to be considered in context of each other.

Examples

  • New feature: directly call a scoped command: npx @scope/cli
    • Current behavior: error: could not determine executable to run
    • Desired behavior: executes the cli (or the only existing) bin from the @scope/cli package. This actually works with the npx in npm@6.
    • I'm not sure how npm exec works internally... if it's just looking for something that's linked into .bin, then maybe there's quite an amount of work involved, but nevertheless - having this feature, and having it be strict, is a primary fix for any spoofing attacks.
  • New feature: create a config with well-known command mappings, e.g. map another-command to always be used from @scope/cli
    • Current behavior: the user has to always call with a --package option: npx another-command -p @scope/cli
    • Desired behavior: after configuring a map/alias in .npmrc the user can call npx another-command without providing the -p @scope/cli
    • There's a large amount of muscle memory to retrain without this...
  • New feature: default --package to current folder
    • Current behavior: cd [path to @scope/cli] && npx @scope/cli (or npx another-command even) would fail, unless @scope/cli is a dependency of itself
    • Desired behavior: if I'm in a folder which has a package.json (or a parent folder has a package.json, and that package.json exposes some bins - I'd like to npx those bins, rather than something that still needs to be installed.
    • Without this, you need to essentially expose the scripts as well as bin and remember to use npm run, instead of npm exec.
    • A workaround I've been using for ages is to npm i -g ., but it would still be nice to get this.
  • Potential security issue: disable behavior to use unscoped command from scoped packages
    • Current behavior: npx cli will execute a cli from @scope/cli if it is installed
    • Desired behavior: npx cli should only execute @scope/cli if @scope is explicitly allowed via some configuration to use shorthand commands, i.e. the user should explicitly tell where to look for the bin either via config, or via --package, or via the first thing suggested here (i.e. scoping the command call itself).
    • As this is a breaking change, it can maybe be introduced as a configuration option, and possibly this can be made the default in npm@8
  • Potential security issue: Disallow running cli when it is installed from multiple scopes
    • Current behavior: when cli and @scope/cli are installed, calling npx cli will execute cli
    • Desired behavior: not 100% certain about what is the right thing to do here, but if @scope/cli comes from my private registry, and cli comes from a deep public dependency, I definitely do not want cli to execute - npx should probably force me to provide a --package when there's any ambiguity (or use npx @scope/cli once that is supported)
    • This is likely a breaking change. Not sure how to go about it at the moment - probably needs discussion.

References

  • n/a

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions