After Alex Birsan’s $130,000 bug-bounty haul last week, hundreds of bogus npm packages have popped up out of nowhere. They appear to have been published by copycat researchers—some of whom have less-than-pure intentions.
Yes, it’s our old friend, dependency confusion, but this time with a twist. Birsan discovered a bunch of private module names and created aliases on public repositories, with higher version numbers.
And, of course, that means he was running his code on other people’s networks. In this week’s Security Blogwatch, we get lost.
Your humble blogwatcher curated these bloggy bits for your entertainment. Not to mention: Discombobulate.
‘Now Publish Malware’ redux
What’s the craic? Careful with that Ax Sharma—Copycats imitate novel supply chain attack:
This week, over 275 new packages have been published to the npm open-source repository named after private components being internally used by major companies. [The] packages are identical to the proof-of-concept packages created by Alex Birsan [who] recently managed to infiltrate over 35 major tech firms and walk away with over six-figures in bug bounty.
Birsan had taken advantage of an inherent design flaw of open-source development tools called “dependency confusion” or “namespace confusion” to squat names of private dependencies used by major companies on public open-source repos including npm, PyPI, and RubyGems. [He] hit over 35 tech firms, [including] Microsoft, Apple, PayPal, Tesla, Uber, Yelp, Shopify.
“It is … only natural to expect other bug hunters, or even malicious actors, to start uploading packages too now, and I have no control over what they do,” Birsan [said] in a statement. [He] believes these attacks are here to stay. … The possibility remains for such attacks to resurface and grow.
Companies should consider squatting their own private dependency names on public repos. … Also, the configuration of your development tools should be evaluated to ensure both private and public dependencies are not being inadvertently pulled from the public repository by default.
And Dan Goodin adds—New type of supply-chain attack:
Last week, a researcher demonstrated a new supply-chain attack that executed counterfeit code on networks belonging to some of the biggest companies on the planet, Apple, Microsoft, and Tesla included. Now, fellow researchers are peppering the Internet with copycat packages.
[Birsan’s] attack starts by placing malicious code in an official public repository such as NPM, PyPI, or RubyGems. By giving the submissions the same package name as dependencies used by companies such as Apple, Microsoft, Tesla, [etc.], Birsan was able to get these companies to automatically download and install the counterfeit code … by giving the packages version numbers that were higher than the authentic ones.
In other words, the researcher was squatting on the authentic package name belonging to the companies. [He] ended up receiving $130,000 in bug bounties. … Both Shopify and Apple awarded Birsan $30,000 bounties each.
This has been a slow train coming for Alex Birsan—How I Hacked Into Apple:
Ever since I started learning how to code, I have been fascinated by the level of trust we put in a simple command like … pip install package_name
When downloading and using a package from any of these … public code repositories … you are essentially trusting its publisher to run code on your machine. So can this blind trust be exploited by malicious actors?
Of course it can.
See that light? Is it the end of the tunnel, or an oncoming express train? Microsoft suggests 3 Ways to Mitigate Risk:
Many organizations use public package feeds — such as Maven Central, npm, NuGet Gallery, and the Python Package Index (PyPI). [But some] organizations fail to treat these uncurated feeds as a potential source of malware.
Unexplained build or test failures should be treated as a potential warning of a package substitution attack. [But] even though the build failed, the attacker likely achieved remote code execution.
1. Reference one private feed, not multiple: … Configuring the package manager to use only a single source isolates you from unexpected public feed changes. [But] ensure your feed is configured to disallow … public packages to override private packages.
2. Protect your packages using … controlled scopes, namespaces, or prefixes: The details vary by ecosystem, but the purpose is to protect a range of package names.
3. Utilize client-side verification features: … These include options such as version pinning and integrity verification.
Heed the work ethic of Markus Dresch:
I just finished reviewing and fixing all pipelines. Took me several hours, but hey — this vulnerability is so scary simple it just waits to be exploited.
But are we asking the right questions? Let ryukafalz ask you this:
Let me ask you this: Why do we consider it acceptable that code you install through a package manager implicitly gets to do anything to your system that you can do? That seems silly! Surely we can do better than that?
In many cases, the dependencies you install don’t need nearly as much authority as we give them right now. Maybe some of these packages need network access … but do they need unrestricted filesystem access?
They don’t necessarily even need unrestricted network access either. What they’re communicating with is likely pretty well-known.
The problem is endemic. Or so says vanyel:
Seems to me all too many things, particularly websites, fetch things from third parties on the fly, making them susceptible to compromise by things they have given up control over, whether it be security or gratuitous changes. Keeping the things you know work local will make things much more stable.
oBvIoUsLy, the answer is blockchain. Now, what was the question? codevark’s suggestion didn’t go down well on HN:
If each new package name were checked against an immutable blockchain of existing names, and was only allowed if it did not already exist either privately or publicly, would that help mitigate this issue?
But it’s turtles all the way down, screams HYS:
I have been bitten by this bug when trying to install a relatively unknown program from PyPI that had a even more unknown dependency. There happened to be another obscure package with the same name as that dependency, and my installation attempt was always trying to install that wrong one.
In the context of security, this becomes a more serious problem. Signing the packages, or using some sort of provider ID would sort out the duplicates.
This is something J2EE did right. (I guess there had to be something.) Here’s a surprised Tomas Langer:
Coming from Java ecosystem … I was expecting that exact versions should be used. … Surprising how many modules depend on “latest” versions.
Meanwhile, brunes69 suggests a nice idea:
Umm, have these folks never heard of a local NPM registry? There are literally a dozen different solutions to choose from here. Do they think commercial vendors download all their NPM dependencies from the internet every time they build?
The moral of the story?
Make sure the code you’re importing really is the code you think you’re importing.
Trigger warnings: Vasquez Rocks, fake rocks, Romulan ale
You have been reading Security Blogwatch by Richi Jennings. Richi curates the best bloggy bits, finest forums, and weirdest websites … so you don’t have to. Hate mail may be directed to @RiCHi or firstname.lastname@example.org. Ask your doctor before reading. Your mileage may vary. E&OE. 30.