Getting rid of NPM scripts
blog.uidrafter.com
blog.uidrafter.com
As far as I know the install scripts can do anything they want, which is upsetting whenever I think about it or they try to do something that annoys the corporate web proxy.
I bet an install script that dumped environment variables, then encoded them into something seemingly innocent like the extra fields of a dns request would gather all kinds of fun info from all the different ci/cd systems.
So while running 3rd party code without inspecting it closely is always risky, its a lot more risky to run via node than via the browser js engine.
CSP [1] can help by preventing malicious code to leak data to third parties, but it's far from trivial to close all loopholes. Especially with the myriad of tracking and other third party scripts most sites/apps use.
[1] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Co...
This is less of a security issue and more of a conventions issue. Also, install scripts often run as root instead of the compiling user.
I used to do something like that 10 years ago. From what I remember, GNU stow was not really able to do that properly though, because of the way it handles nested un-existing directories. I. E. It will symlinks a whole directory if it does not previously exist, which will make later deployments of new symlinks inside impossible. Also it did not handle absolute symlinks.
For these reasons, I used "xstow".
Edit: just had a look at the latest version of GNU stow, looks like they corrected the folding issue, that's great!
I'm not sure what you suggest here. Chrome extensions are heavily sandboxed and thanks to that you can remove them cleanly. Does this mean that Chrome replaces OS package management? Is your intent to say that making npm installation more "dangerous" for users is a good idea as it drives people towards OS package management? What about the large set of software that is not won't ever be packaged for your distro/OS?
[1] https://zolk3ri.name/cgit/zpkg/ (https://zolk3ri.name/cgit/zpkg/tree/src/zpkg.ml)
It's certainly more complicated to set up than a simple "the CI system invokes a single shell script that does everything" build, but it's not actually that complicated and every CI system I've used has supported doing this.
It came about because I ended up having a spat with one of the NPM engineers at the time because they launched npx with the ability to run arbitrary gists[2] and this was before 2FA (FWIW you can still absolutely do this with npx).
I wrote a proof of concept[3] that showed you could, inside a package.json add a command to install another package from a gist location, and then use that to steal credentials, bash history, etc.
[1] https://github.com/tanepiper/npm-lint [2] https://medium.com/@maybekatz/introducing-npx-an-npm-package... [3] https://github.com/tanepiper/steal-ur-stuff
It's convenient but, in my opinion, at a cost of "magic" being done to my machine with a "don't worry about it" attitude.
A UX I could get down with would be "npx run git-open" followed by a short CLI that tells me what it's about to do, why, and asks for confirmation.
Every new framework has to re-imagine and re-invent what has been done forever. Not only that, we need to wrap it with new jargon, because otherwise it'll not be the next cool thing (TM).
Regardless of the framework, we finally end up with a declarative format for representing things. But that isn't how it is planned from the beginning. Instead, an entire generation of developers go through one version, and then have to migrate to the next version which breaks everything. So now we have groups of developers defending their decisions.
Considering that most of the frameworks are open source, I don't see a collective approach to designing APIs. Yes, I know about web components, but that isn't going anywhere in the near future. </rant>
"just" is a utility designed to execute programs: https://github.com/casey/just#just
1) ./make can be more portable e.g. you might use some GNU Make syntax that does not run on BSD and have to insall gmake just to run that
2) Make is not designed to be a command runner and have to manually add .PHONY to everything
3) case looks minimal and flexible enough (although I'm sure sh's confusing syntax can cause a lot of pain for non sh experts like esac wtf)
1) I suspect GNU Make will be installed on any system where node code will run.
2) You don’t have to .PHONY anything that will never be a real file.
3) My bet is the Makefile will be shorter and clearer, but I am of course biased since I’m used to the syntax.
`$ which time
time: shell reserved word`
It's that given the depth of the dependency trees, I don't have any confidence we can tell the difference between trustworthy and untrustworthy packages.
Also what I'm not sure I understand is: if you are installing a package that you don't want to run as a binary, it's probably that it's a library that you are going to import at some point. At this point, the malicious module will then be able to run arbitrary code with the same right as the current user...
Which makes me wonder: Should dev machines be considered high-risk? They run all sorts of software, with permissions loosened, then pass programs to CI tools, which build them and deploy to prod with AWS authentication tokens enabled... I’m shaking just seeing how many Chrome extensions my devs have (with all permissions enabled of course) when they access prod instances...
Should startup management (Safe environnements with Excel, no Chrome extensions, accessing the company’s bank accounts, etc) be done on separate machines than development activities?
I do some basic steps to harden my dev machines:
- A Chrome profile without extensions for developing for the most part.
- The localhost is not 127.0.0.1 but a random IP under 127/8, with a random port. See https://news.ycombinator.com/item?id=20028108
- When creating SSH keys, add extra rounds (e.g. `ssh-keygen -a 64`) to make it harder to brute-force the passphrase.
At any rate, do you agree those issues would be unrelated to NPM scripts? I ask because my point is more like: one mitigation at a time. Otherwise, many people would do nothing because it wouldn't solve everything.
Also, developers adding new packages could compromise their environment because that's done running e.g. `npm install react`.
Why does npm execute scripts by default if they are not to be trusted?
Why would anyone install some software via npm unless they are confident it isn't malicious?
Why does npm use a single flag for scripts in all contexts and if this thing is a known problem, why don't they add a flag for handling this specifically?
And no, just staying with js isn't enough to be cross platform - but you'll be closer.
I don't see why a package would have a backdoor in install, but not run - or not in the package code itself?
It's easy to write, definitely executed (if not for the settings suggested by the blog posts), doesn't depend on the usage of the library by the victim, and you don't really need to know anything about the setup the victim has.
You are right in that it's not the patch that fixes the entire problem, but that is rarely the case in security.
Source: earlier this year i analysed every package dependency compromise between 2006-2017.
https://www.haukeluebbers.de/blog/2020-01-timeline-of-packag...
You can see that the most common method for npm, Rubygems and pypi is something like "Method: executed by install hook"
I'm using esbuild (https://esbuild.github.io/) in a monorepo setup currently and the time to build the whole repo (~200ms) is the same as the overhead of running `yarn command`.
Running `yarn esbuild ...` is ~400ms, running `esbuild ...` directly is ~200ms.
Which uses `eval "$@"` and bash functions, which let one pass arguments to your scripts. If you call the script file `run`, you end up with `bash run my-task`.
Npm errors out if the sub commands generate a nonzero exit code. I’ve fixed so many bash scripts that ignore errors and just keep going.
npm doesn't implement permissions. node doesn't implement permissions.
deno does have slightly more emphasis on security, but JavaScript is not and will never be a security focused language. Everything is mutable, even type definitions.
The way javascript ecosystem designs its products affects basically everyone with an internet connection. It's almost like they had a moral responsibility to improve themselves.
How about a typo? malicious actors can benefit from this.