Remix.run Logo
TZubiri 5 hours ago

Looks good? But doesn't this just change the compromise window from first installation to first run?

semiquaver 4 hours ago | parent | next [-]

Ok? Not sure what a package manager can do about the fact that eventually you want to run the things you install.

grassfedgeek 4 hours ago | parent | prev | next [-]

"First run" doesn't exist for JavaScript libs used only in web apps. So for that entire class of packages this change makes them safe.

tabwidth 3 hours ago | parent | next [-]

Build tooling still runs though. Your bundler plugin or PostCSS transform gets full fs access at build time, nobody's auditing that.

TZubiri 2 hours ago | parent [-]

Build deps are even disregarded as less critical than runtime deps traditionally. So deps like sphynx for building docs are still a dev side supply chain vector.

https://github.com/kennethreitz/pytheory/issues/47

The reason this may be overlooked is because build deps are only ran by the devs, but not the users, so users dismiss it as safe. However, if a build dep is infected, the infection may spread to the actual package code, which will then of course be run by the user.

Not theoretical, Microsoft is currently under attack by a worm that spreads through vs code extensions, which then spread to actual packages that users run.

WatchDog 3 hours ago | parent | prev | next [-]

"First run" certainly exists in web apps, it's just running JS in a browser rather than a shell script on a developer or CI machine.

There is plenty of malicious stuff you can do from the browser.

TZubiri 2 hours ago | parent | prev [-]

But this is npm, the execution environment is not the browser, but the server.

Most packages are imported via import/require, even if it's a browser only package. Because of SSR and reasons.

Or maybe not, let's look at a random browser only example, angular and react will use SSR, so they will execute in the server, let's check Jquery:

https://www.npmjs.com/package/jquery

Docs suggest just using a script tag instead of npm, when using npm install, they suggest to run import statement, which can execute arbitrary code.

The bottom line seems to be that if you are using npm, it's cause you are using node, and therefore you will run the imported code in the server, otherwise you would use a script tag.

But maybe there's a way to define a browser only package or .js URL such that it is only downloaded and served but never executed server side?

In any case, not a huge usecase of npm, which again, is designed for node which is backend.

Randome example,

include

christophilus 5 hours ago | parent | prev | next [-]

Better than nothing. That’s the same problem every package manager has.

insanitybit 4 hours ago | parent | prev | next [-]

Yes, but that's actually a huge win. I can't know what a package needs to do at install time - the dev knows that. But I know what my tests and program need to do at runtime because it's my job to understand those things.

The dev has to be responsible for ensuring that their build scripts are safe, I need to be responsible for ensuring that my runtime is safe.

It'd be great to have more tools for untrusting libraries (iframes are awesome for this on the frontend) but this is still a massive win.

Someone1234 4 hours ago | parent | prev [-]

I’m sure we’d all welcome your alternative and or superior proposals.

Without that, this just comes across like unconstructive commentary.

This moves the needle a little your proposals or the lack thereof don’t move it at all. So I’ll take this over nothing.

spartanatreyu 3 hours ago | parent | next [-]

We already have alternative and superior proposals, it's called Deno.

It's node + npm compatible and its permission system locks everything down by default.

If you know ahead of time, you can turn on which permissions something is supposed to have in the config file.

Or you can just not use a config file at all. Anytime it needs a permission: it asks you what it wants. You can say yes or no, and those are saved in the config file for next time. If you say no, the script throws an error where it tried to access something it didn't have permission for.

---

Example:

- My linter wants access to my file system?

  - You can have read access to ./src/ts/
- My bundler wants read and write access to my file system?

  - You can have read access to ./src/ts and write access to ./build-output

  - Huh, what's that? The bundler was trying to both read and write a file in ./src/ts?

  - We don't want input files getting overwritten, that's a recipe for hard-to-diagnose race conditions. Looks like the permission system did more than just keep things secure, it's like a type system for IO.

  - Oh, look at that, there was a very subtle bundler misconfig, let me fix that now. How long would that have existed if we didn't use deno...
- Oh what's this? An updated dependency I've been using for 6 months suddenly asking for access to my .env file, and asking to run curl in a separate process? How about "no". Why would a simple DOM utility dependency be asking for those permissions? Ah, looks like it was part of a credential stealing supply chain attack. Glad I wasn't using node.

---

Addendum: Node now has a permission system, but it's broken by design so it's useless.

TZubiri 31 minutes ago | parent | prev | next [-]

You'll notice that my comment was a question, you can tell by the presence of question marks at the end of the sentence.

Additionally, if a comment were to hypothetically point out an issue, that is valuable on its own. If someone reacts to a comment that points out an issue this defensively, it's a huge red flag.

mschuster91 4 hours ago | parent | prev [-]

An idea might be to not just pin "package xyz allowed", but "package xyz postinstall allowed with hash <1234>".

jffry 3 hours ago | parent [-]

The default behavior for the automated "add everything existing to the allowlist" is to include the specific version: https://docs.npmjs.com/cli/v11/using-npm/config#allow-script...

Together with a lockfile that does achieve "package xyz postinstall allowed with hash <1234>"