pnpm / pnpm

Fast, disk space efficient package manager

Home Page:https://pnpm.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Protection against lockfile injection attack

ai opened this issue · comments

Describe the user story

We need some solution from lockfile injection attack.

(It also could be a huge selling point for pnpm.)

Describe the solution you'd like

  1. We can have an allow-list of hosts and some simple checks that URL is valid to package name and version.
  2. During install, we can check every record with this simple checks (is it npmjs.com URL? Does package name and version match URL?)
  3. If we have a non-standard URL, we run a more slow check, that URL is the real result of package.json. For instance, if package.json has non-standard package with full URL in version.
  4. Additionally, we can add option to define allow-list of domains (and maybe enable it in next major).

Describe the drawbacks of your solution

It could affect performance. But this two-check way should not create any problems for most of use cases (where we have packages from npm).

Describe alternatives you've considered

We can define allow-list of domains, but it will not fix the problem. We can publish is-nummber-bad and replace is-number’s URL in lockfile to is-nummber-bad URL.

We can create an allow-list of both domains and package names

or an allow list of authors. I am not sure if that is possible.

We can create an allow-list of both domains and package names or an allow list of authors. I am not sure if that is possible.

My dream is to have protection without any config.

We assume that developers check the package.json changes, but could miss changes in lockfile.

So, we need to check that lockfile was generated from that package.json to be protected from this attack without any config.

(Host allow-list is just an extra layer of protection which will be used rarely)

The issue is that the lockfile is generated locally. If we could delegate lockfile generation and storage to a server, then it would be more secure and faster.

If we could delegate lockfile generation and storage to a server, then it would be more secure and faster.

It will require to change infrastructure in all projects and is not very flexible. Very likely that it will be impossible to convert the whole community to the new system.

But if any package manager will give a solution for this dangerous thing, this package manager will get an excellent selling point. “Use pnpm because it is safer than npm” looks very good for big companies.

I agree. For example, we wrote a .pnpmfile.js https://github.com/DimensionDev/Maskbook/blob/develop/.pnpmfile.cjs to manually make a approved list.

“Use pnpm because it is safer than npm” looks very good for big companies.

For big companies an allow list is fine because in big companies each new package that is added to a project should be approved.

For big companies an allow list is fine because in big companies each new package that is added to a project should be approved

You need to give a solution for middle-size companies to create “Use pnpm because it is safer than npm” trend.

Projects where you need to approve each package has very low risk of this attack. They are mostly closed projects without PR from anyone outside.

Open source projects who accept PRs are in the most dangerous position. But they will not be able to create an allow-list of all packages.

The problem with your suggested solution is that it will drastically increase the amount of filesystem operations, when the lockfile is up-to-date. If we don't trust the lockfile, we need to read each package's package.json file during each installation. So we will get +NUMBER_OF_DEPS filesystem operations per each install. Is the risk big enough for this sacrifice? Just an allowlist of domains (or maybe authors) would make everything safer without the speed sacrifice.

Fair point 😞

Another way: add extra option --validate-lockfile and use it in CI for pull request. But will it be easy to write these configs? Maybe we can convince GitHub Actions to add additional environment variable if PR came from another user and set optional automatically?

This sounds better. Or it could be a new command. Something like pnpm validate-lockfile

So validate-lockfile is just a clean install and check it with the current lockfile content?

If it will be a new command then I think it will just fetch the metadata of every package that is in the lockfile and verify that all the entries are correct.

Btw here is related discussion in yarn → yarnpkg/berry#4136, if it will ever be useful

Happy to read about this making it into pnpm. Has there been any progress on this by anyone?

Can someone provide evidence of successfully manipulating pnpm-lock.yaml for injection?

  1. pnpm doesn't maintain the tarball source to fetch so there's no way to inject a different one there
  2. I tried injecting new packages into the lockfile (that aren't in package.json) and pnpm doesn't install them so it can't mutate its state

I would like to know if there's an actual threat beyond these to lockfile injection for pnpm but not sure yet there's a case there.