Live data from Hacker News

Dependency Confusion: How I Hacked Into Apple, Microsoft and Other Companies

medium.com

121–130 of 412 posts

Re: Dependency Confusion: How I Hacked Into Apple, Microsoft and Other Companies

#121
post #85
post #78

> The packages had preinstall scripts that automatically launched a script to exfiltrate identifying information from the machine as soon as the build process pulled the packages in. Pre and post install scripts in NPM packages are such a terrible idea. Even when it’s not malware, it usually just a nagging donation request with a deliberate “sleep 5” to slow down your build and keep the text displayed.

Are there many package manager that do not have either pre-, post- or build scripts or plugins allowing arbitrary code execution during build? pkg managers that do have that: cargo (build.rs), pip (setup.py), npm (install scripts), apt/rpm/pacman (postinstall hooks) Maybe the only exceptions are Go and Java package managers?

I'm pretty sure all package managers which produce packages which might bind to C do have "some form" of pre-, post- or build scripts.

The reason is simple because without it you can't properly bind to system libraries.

And even without, the supply chain attack still works against at least developers as packages are not just build but also run, often without any additional sandbox. (E.g. you run tests in the library you build which pulled in a corrupted package).

The main problem here are not build scripts (they still are a problem, just not the main) but that some of the build tools like npm haven't been build with security but convenience as priority and security was just an afterthought. For example npm did (still does?, idk) not validate if the packag freezing file and the project dependencies match so you could try to sneak in bad dependency sources.

Also for things which are classical system package managers (i.e. not build tools) like apt/rpm/pacman it build scripts really does not matter at all. The reason is that what you produce will be placed and run in your system without sand-boxing anyway, so it's a bit different then a build tool which is often used to build binaries (installers, etc.) at one place and then distribute them to many other places.

Edit: Another attack vector is to bring in a corrupted package which then "accesses" the code and data of another package, this could use speculative pointer accesses or similar but in languages like Java,Python, JavaScript you often can use reflections or overriding standard functions to archive this much more reliable.

Re: Dependency Confusion: How I Hacked Into Apple, Microsoft and Other Companies

#122
post #84
post #17

The real solution is to design and build software components that can be finished , so they can be ruthlessly vetted - rather than the endless churn of updates.

Gamers often complain how they become free QA testers if they buy a game in the first few months after release as most games are full of bugs (hi Bethesda!) but it is way worse in things like JavaScript libraries etc. It's as if finished have become a foreign word to most developers. Look at the resent story about Linux stable kernels that have had more than 255 minor releases and think how much of a shit show it wou…

> Look at the resent story about Linux stable kernels that have had more than 255 minor releases and think how much of a shit show it would have been if they added features too like most developers do.

At least some distribution kernels do new feature backports - mostly to support new hardware on LTS versions (like e.g. Ubuntu did for the Raspberry Pi, see https://github.com/raspberrypi/linux/issues/3464).

Re: Dependency Confusion: How I Hacked Into Apple, Microsoft and Other Companies

#123
post #58

Earlier quoted context omitted.

Or the URL-based model used by Go.

What does the url model bring? Packages are typically considered immutable once published. If I have a particular package e.g. "FooLib.Bar v 1.2.3" then this zip file should _always_ contain the same bits. If I need to change those bits, e.g. to fix a bug then I need to ship e.g. "FooLib.Bar v 1.2.4" Also packages aren't always small. So it makes sense to cache a copy locally. On dev machine "package cache" and in an…

Using a FQDN is less likely to be unknowingly hijacked when it's a domain they control and use daily.

URL references also contain the version number, typically an immutable Git tag reference. They also benefit from just needing to download the source code that's referenced and not the entire package. With Deno you can also optionally host versioned 3rd Party packages on their deno.land/x CDN.

URL references are also cached locally on first use and can be used offline thereafter.

Re: Dependency Confusion: How I Hacked Into Apple, Microsoft and Other Companies

#124

I’m cackling at how great this is. This is what happens when you trust the internet forever and just scarf down any old thing at build time. Of course it’ll get exploited! That’s what evil people do.

There's more coming.... tons of github integrations ask for blanket access to your account vs Oauth, ( https://github.com/marketplace ). Tons of github users give that access, the access_tokens are only a password type breach away. If you have these access_tokens you can edit the repos they are for all you want.

I wish GitHub would create a proper auth design. I won’t grant blanket permissions to tokens because there’s too much risk of something going wrong.

It seems dumb that they don’t have per repo tokens. I think the issue is with their licensing as if they made proper tokens users could abuse it by giving tokens to their friends. But this should be detectable in a friendly (please don’t do that) way.

I want to be able to give read-only access to private repos.

I want to be able to give fine grained function level and repo level access.

If I’m an admin on multiple repos, I want to be able to issue a token for just a single repo so I can give that to a CI job without worrying if every single repo I admin is at risk.

They allow ssh keys with some similar functionality, but ssh keys can’t be used as much as tokens.

I’ve been waiting for a story about how some third party app granted access to my whole org gets taken over and wreaks havoc. Eventually this will probably be the attack that alters real packages instead of these name overloading packages.

Re: Dependency Confusion: How I Hacked Into Apple, Microsoft and Other Companies

#125
post #58

Earlier quoted context omitted.

Or the URL-based model used by Go.

What does the url model bring? Packages are typically considered immutable once published. If I have a particular package e.g. "FooLib.Bar v 1.2.3" then this zip file should _always_ contain the same bits. If I need to change those bits, e.g. to fix a bug then I need to ship e.g. "FooLib.Bar v 1.2.4" Also packages aren't always small. So it makes sense to cache a copy locally. On dev machine "package cache" and in an…

For better or for worse, many projects auto-update their dependencies these days.

They do this to address the shortfalls of modern conventions like small packages, continuous release cycles and dependencies nested several layers deep.

So if you were using the internal package FooLib.Bar v 1.2.3 and an attacker posts FooLib.Bar v 1.2.4 to a global repository, anyone using auto-updating will update to it.

Re: Dependency Confusion: How I Hacked Into Apple, Microsoft and Other Companies

#126
post #117

Pulling packages down at build time seems ludicrous to me, I can understand it in a development environment, but I don't understand how "Pull packages from the public internet and put them into our production codebase" past any kind of robustness scrutiny. I guess it's a case of the ease of use proving too great, so convenient in fact that we just kind of swept the implications under the rug.

> I can understand it in a development environment

I can't. It's incredibly wasteful time and resource-wise, and ties your development process to third-party providers (and your ISP), which fall over often enough in practice.

It's a good practice to have a local cache of all the third-party dependencies you use, available to both developers and CI infrastructure.

Re: Dependency Confusion: How I Hacked Into Apple, Microsoft and Other Companies

#127
post #44

This post seems like a good time to note that by default, there's no direct way to verify that what you are downloading from dockerhub is the exact same thing that exists on dockerhub [1]. Discovered after seeing a comment on HN about a bill of materials for software, i.e., a list of "approved hashes" to ensure one can audit exactly what software is being installed, which in turn led me to this issue. [1] - https://g…

I remember when we used to sign binaries and packages and nobody checked the pgp files anyways. We could have something similar better today, just need to be automated enough.

Re: Dependency Confusion: How I Hacked Into Apple, Microsoft and Other Companies

#128
post #25

I know that node has `package-lock.json` and `yarn.lock`, which include integrity checks. Are these checks decorative only? How could npm have been affected by this issue?

IIRC you need to use npm ci to ensure that package-lock.json is used. That said, when developing locally you are going to use npm install or npm update and update the package.json and package-lock.json files accordingly. I could be entirely off target here since I'm writing purely from memory. But there seems to be a few different ways one could trigger a pull from the malicious repo and end up with it inside the pac…

No that's not correct, in fact this comment and the two sibling comments are both wrong.

Quouting from NPMs documentation[0] for npm install

> This command installs a package, and any packages that it depends on. If the package has a package-lock or shrinkwrap file, the installation of dependencies will be driven by that, with an npm-shrinkwrap.json taking precedence if both files exist. See package-lock.json and npm

Consider an example where in package.json you have `"react": "^16.11"` and this has been resolved and fixed in package-lock.json as 16.12 at a previous point in time. Running npm install will not cause NPM to install 16.14 even though it matches the pattern specified in package.json, instead 16.12 will be installed because that's what package-lock.json says.

What npm install does do, is detect if you've made changes in package.json and only then does it re-resolve the dependency. In the above example, if you changed `"react": "^16.11"` to `"react": "^16.14"` in package.json and then ran npm install the package-lock.json would be changed and version 16.14 would be installed.

Bundler and CocoaPods also work this way.

Re: Dependency Confusion: How I Hacked Into Apple, Microsoft and Other Companies

#129

I used this version trick in nuget, but the other way around. To update existing non-maintained public packages, mostly because they were on. Net framework and a lot moved to .net core. In visual studio you can set the priority of where packages have to be checked. My own package repo has a higher priority. I never thought about using it as an attack vector though.

I believe you can work around this attack vector .NET by referencing strong-named assemblies.

Re: Dependency Confusion: How I Hacked Into Apple, Microsoft and Other Companies

#130
post #117

Pulling packages down at build time seems ludicrous to me, I can understand it in a development environment, but I don't understand how "Pull packages from the public internet and put them into our production codebase" past any kind of robustness scrutiny. I guess it's a case of the ease of use proving too great, so convenient in fact that we just kind of swept the implications under the rug.

Migrating from public NPM to a privately-hosted, your own mirror of NPM is not a very complicated process, and if you already have a CI pipeline in place, it can be implemented completely transparently to developers. But as many other things that an organisation has to change as it grows from a single-founder startup to a real company, it's something many people just forget to do until they face the consequences.
Post reply on HN