-
-
Notifications
You must be signed in to change notification settings - Fork 936
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Filter binaries that are installed to node_modules/.bin
to avoid collisions with system-wide binaries
#3610
Comments
Related issue: #1488 Although the proposed solution of adding a property to |
Wouldn't just a simple allow list be sufficient? {
"linkBins": ["foo", "bar"]
} |
If you think being able to configure individual packages is overly complex, I could live with that simplified version. It doesn't solve the issue of picking which package gets to install a specific bin, in the case of conflicts. In which case this'd no longer be a solution for #1488. We could specify that {
"linkBins": {
"*": ["foo", "bar"]
}
} if you're just worried that the syntax is overly complex for common use cases? We'd also need regex syntax: {
"linkBins": "^(?!bar$).*"
} if we wanted to retain the ability to exclude specific bins, but accept everything else. In my opinion, I'd like to retain the ability to specify which packages install which binaries. |
I have created an RFC in the Yarn repo yarnpkg/rfcs#118. The consensus was that it is not the package manager's problem if there are conflicting bins. Regarding regex support, if it is only needed for excluding, I would probably suggest just a dedicated field for that. {
"ignoreBins": ["bar"]
} |
cc @pnpm/collaborators |
Specifying which binaries get installed per package would be a great security improvement. For package aliases, pnpm add foo@npm:bar@2 {
"linkBins": {
"foo": ["bar"]
}
} Using a separate field for linked and ignored bins reminds me of typescript I'm interested in how a name conflict would be resolved with this proposal. Let's say there is a conflict with the bin utilities named
I want to pick {
"linkBins": {
"pkg-a": ["org-x", "org-y", "org-z"],
"pkg-b": ["foo", "bar"]
}
} {
"linkBins": {
"pkg-a": ["org-.*"],
"pkg-b": ["*"]
}
} {
"linkBins": {
"pkg-a": ["^(?!foo|bar$)"],
"pkg-b": ["*"]
}
} {
"ignoreBins": {
"pkg-a": ["foo", "bar"]
}
} {
"ignoreBins": "^pkg-a\\.(?:foo|bar$)"
} |
This should be discussed with npm and Yarn teams as this will influence how depednencies are installed (if they are published with these new fields). So an RFC should be created in this repository: https://github.com/npm/rfcs |
Describe the user story
Allowing dependencies to add arbitrarily named binaries to
node_modules/.bin
leaves users vulnerable to conflicts between the binaries installed tonode_modules/.bin
and system-wide binaries.For example a malicious package installing
sudo
could be used to harvest passwords when accidentally executed by a benign package script like"serve": "sudo nodemon ./app.js"
. Some users even addnode_modules/.bin
to their shell session'sPATH
for the convenience of avoidingpnpx
everywhere.I am specifically motivated by discovering that some system-provided binaries that I rely on could collide with binaries provided by dependencies, for example: foreground (execline) might collide with the binary foreground (foreground). On my system, I counted 345 potential collisions between system-wide binary names and those provided by various NPM packages.
Describe the solution you'd like
I want to be able to restrict which binaries get installed into
node_modules/.bin
. I propose adding a"installBins"
property topackage.json
that specifies which binaries get installed per package.A binary defined by a package may only be installed if:
installBins
and the rule matches the binary."*"
and that rule matches the binary.A rule matches a given binary name when:
RegExp(rule)
.The rules defined in the root package only affect binaries installed in
$root/node_modules/.bin
and do not affect binaries that get installed in$dependencyDir/node_modules/.bin
. However, every dependency, direct or transitive, would filter its own$dependencyDir/node_modules/.bin
by its owninstallBins
rules when installed.Describe the drawbacks of your solution
installBins
doesn't break when installed as a dependency by another package manager. Although I hope to convince other package managers to adopt this convention./^(?!bar)(.*)$/
will match every binary except forbar
. The array syntax could be extended such that["*", "!bar"]
behaves the same as the former RegExp, but I am unconvinced.node_modules
, since there's one merged.bin
for all of the dependencies. Merging theinstallBins
rules for all of the dependencies could be a costly operation.Describe alternatives you've considered
package.json
. But packages shouldn't behave differently depending on whether they're top-level or installed as a dependency. So these rules ought to be part of the package definition.--no-bin-links
and manually install the necessary binaries via a post-install hook. I'd have to switch away frompnpm
, and this doesn't help when the package is installed as a dependency.--prefer-system-path
that causes pnpm to appendnode_modules/.bin
to thePATH
rather than prepending it when running scripts.--warn-on-binary-collision
that causes pnpm to warn or prompt for user interaction when it detects that a binary would collide with a system-provided binary.The text was updated successfully, but these errors were encountered: