Embedded Malicious Code in node-ipc
github.com
github.com
Years ago I chose to pin/lock all dependencies, even transitive dependencies (direct dependencies' dependencies) to much disagreement from the semver purists.
Crypto developers are extra high value targets because they likely access their wallet from the same machine they develop on. So I've taken a very hard stance on this, even feel we should do even better by disallowing updates for new releases (I realize adequate security here is not practical/feasible for most).
To make matters worse: devs often install npm packages with sudo (and I have a canned response for sudo related issues telling them that they must now format their drives to fix it, and even that might not be enough as their bios and other embedded firmware could also be compromised).
Meanwhile, yarn, a popular npm alternative, will NOT respect a package author's wishes to lock transitive dependencies. It's maddening (don't use yarn until/unless they fix this).
The only time a dependency shouldn't be pinned is if you are also the author of that dependency.
Anyway, people would say I'm fun at parties, but they stopped inviting me long ago.
Though now that wasm is popular and there are Rust implementations of Ethereum, I still think being able step into and debug from within a JavaScript application is valuable.
I think the ecosystem has just drank too much semver Kool-Aid.
So no, I don't regret it, and I don't think the problem is unique to npm, I think the problem is exacerbated by its popularity and addiction to loose semver (the default when installing a package by name).
Anyway, semver makes me sad sometimes. Haha
I build library X and ship it with a lockfile to lock all transitive dependencies.
User installs library X, even though I ship a lock file, it isn’t respected. (I assume this makes Resolution way to complex)
If you ship a library where everything is locked, one should consider vendoring their dependencies. I think this is what npm does itself. (Or used to do). Or consider reducing your dependencies.
I can’t speak to Yarn’s motivation, but I suspect for most Yarn users it’s not dissimilar to my own: pinning exact versions of transitive dependencies can be a big source of “audit fatigue” with NPM. It’s fine that authors wish to limit the surface area of version ranges they support, but for downstream users this can often mean being essentially held hostage with potential exposure to vulnerabilities and no reasonable alternative.
Yarn should, like NPM, default to honoring all pinned dependencies. Both now have facilities to override those defaults (resolutions/overrides respectively), which is important. But there should also be a more gentle middle ground of “yes I want to assume this library meant to use semver, I understand I’m slightly relaxing the contract in the lockfile” in the form of a CLI flag… rather than manually writing potentially hundreds of lines of JSON.
> Or consider reducing your dependencies.
I mean, that sounds nice in theory. But the whole number of dependencies thing is a systemic design problem more than anything. No one is installing 1000s of dependencies. They’re installing ~5-10 and getting 1000s.
Yes, this! I want this, and for all nose package managers to share a lock file format.
I wish more tools were able to concisely show you the differences between dependencies, but… sometimes dependencies have binaries and at that point you might need to fork or clone and build your own version of a dependency. I’d suggest only using dependencies when you can read and understand the code, but there are always limits. I can’t think of the last time I thought of a glibc dependency except when using Alpine or compiling something for Cgo. But it’s still something to keep in mind: that sometimes your project will be simpler and easier with fewer, smaller dependencies where you can read the code in full.
1: https://yarnpkg.com/features/zero-installs#does-it-have-secu...
For library authors that want to take reasonable precautions yarn makes it very hard. Though some suggest leaving transitive dependency updates up to the consumer makes yarn more secure, as they can update to the fixed packages sooner.. but I don't believe this benefit actually manifests often.
I guess the moral of the story is that semver is really great on paper, but people suck at it, sometimes on purpose.
By publishing the source code to git, those who desire to use a specific version could alternately embed the git URL in their dependencies instead of the pre-built npm package.
Yarn Pack command can be used to run a build command[1] and Yarn Publish[2] in turn calls Yarn Pack, if I understand this correctly.
1: https://yarnpkg.com/advanced/lifecycle-scripts
2: https://yarnpkg.com/cli/npm/publish/#gatsby-focus-wrapper
That said… I agree that further work might be necessary here. I remember the first time I built an npm package and was confused when my lockfile in the package was completely ignored for dependency resolution. I don’t think this problem has gotten much attention, but the solution above might substantially solve the problem, if your dependencies are small enough to embed easily. It’s not ideal though, and I’d welcome other perspectives.
That said, the miracle of compression (and Yarn PnP not needing to uncompress) means you could have duplicate code and it won’t cost you much at all.
Another option would be to maintain your own dependencies by code splitting at the npm module level, but that could be considered an API-breaking change, I suppose, if the goal is to reduce how much is distributed by splitting out platforms.
You could also publish one layer of dependencies, probably, and still have exact versions pinned, but that would require maintaining CI build tools for your dependencies to ensure they are entirely built with no further dependencies or relying on republishing prebuilt no-dependency binaries in your own namespace.
I am reminded of how before tree-shaking became commonplace, it was routine to export libraries as lots of tiny npm packages, one per function sometimes, and import just the functions you needed as their own packages. That was taking it too far, and ECMAScript Modules (ESM) standards have somewhat replaced it, though for best tree-shaking you have to ensure your JS is actually modular and has no global state or side-effects when importing, which means you end up breaking some JS code when turning on Closure Compiler’s advanced mode, for example.
But we’re deep in the build optimization weeds now… the big advantage to pre-compiling libraries though is that you don’t have to tell others what build toolchain to use and instead provide standard ES5, ES6 or whatnot, already pre-compiled and ready for use (or… maybe, further tree-shaking…)
The current best practice, as I see it, is is a disposable chromebook, backed by a cold wallet which holds the keys to the multi-million dollar hoard.
Do you mean locking transitive dependencies across an upgrade of a direct dependencies? How does npm do that?
On the other hand, the people that sent SWAT teams to his door and sent death threats are equally threatening the trust foundations of FOSS.
Link to the vice article talking about SWATing: https://www.vice.com/en/article/dypeek/open-source-sabotage-...
That people call SWAT teams on the maintainer, I hadn't heard, but that's so much worse. The effect is also rather different. I don't have much OSS, and certainly nothing of any importance, but I'm going to keep the project I'm working on private. Too bad if someone else might have been interested.
The difference is the possibility of actual bodily harm vs restoring a pc from a backup
Also for the record no please don’t bust out the swat team for a burglar, bit much
In this case I'm saying the in person scenario is more likely to end up in a dead or injured person. They both remain bad choices.
absolutely, yes, I strongly resent my neighbours who call for deadly force in response to petty property crime.
Someone breaking into my house to steal something while my family is home? They're getting shot in the forehead. I don't know their intentions, nor am I going to assume the best of intentions.
But I agree, SWAT in response to this is overboard. I would've been glad to see the author get proportionate repercussions (perhaps his Github/NPM accounts being deleted) as we know his intention, but putting his life in danger is too far.
It doesn’t take much for police or the people inside to get shot and possibly killed during raids. Many innocent people have been severely harmed. Infamously, an officer threw a flash bang (an explosive grenade with burning magnesium) through a window into a crib with a child in it. Another fired shots that went through the wall and killed a woman in another apartment. At least one police officer was shot and killed by an innocent home owner in legitimate self-defense.
This isn’t something to take lightly. Whether it not it was the caller’s intent, they tried to get someone killed.
Where are you getting this?
"Miller told IT Pro that he had been swatted"
From: https://www.itpro.com/development/open-source/367129/open-so...
Because he went from posting a heart emoji to deleting files.
Edit: I think I would actually like to see a lawsuit come out of this example.
Honest question, what can be done to address this type of issue? Lock fines are great and all but people rarely dig into their dependencies when upgrading.
How are you guys dealing with upgrades?
I remember watching a Walmart talk on Node.js and how they vet every single update to every single module before they pull it into their internal repository for internal distribution. Perhaps the answer is to stop blinding pulling down dependancies from the internet?
Most organizations are not as big as Walmart?
However, if the Walmarts/FANGS/etc with huge mega teams would publish their audited versions, that would be something. However, that seems like a liability without any potential gain for the mega teams.
Unlikely.
> undermines the ecosystem due to the loss of trust.
Good, that trust was always misplaced. At least it’s only Russia and Belarus getting screwed instead of everybody getting hit by ransomware.
* Despite the motive for the act there is actual malicious code injected in a library without notifying or disclosing any information.
* The whole act was not well thought out. The check is rudimentary to put it gently, or plain naive to say it straight. Not only Russians are targeted but also anyone having vpns or other legitimate reasons to run under Russian IPs. Finally the check is crude and might as well fail at some point, with devastating effect.
* Author seems to be removing github issues, hiding conversations and doing damage control now that this backfires.
“FOSS developer” is hardly a career. Nobody is losing out on income by you blacklisting their projects.
The most obvious is former Soviet republics, or any neighbour of a target nation, being mis-identified. That includes Ukraine itself, by the way, but also Finland and Poland. How about territory that is disputed? Or adjacent to enclaves like Kaliningrad? But it can also include friendly-nation assets that just happen to be currently inside Russia or Belarus, including government entities and journalists. It can affect folks simply relying on mobile networks near borders. Address blocks are routinely reallocated, reassigned, reused, misused, on a global basis and an address range announced in Korea last year can show up in Canada tomorrow.
Even geolocation by client-side request can be wrong, too. Not just because it's easy to lie, but major nations also fuck with the GPS, which is an issue currently affecting Baltic aviation¹. By the same token, IP geolocation databases are easily misled by self-reporting from mobile devices. Simple example: imagine someone using a dedicated VPS in the US as a personal VPN exit node for their devices when visiting mainland China (actually, we don't have to imagine: I did exactly this). Any IP-based location assumptions start out incorrect, since it's by VPN exit IP; but later on, thanks to mobile device reporting, that IP address can end up misclassified long-term as "Chinese".
None of this is hypothetical. I visited Jordan a few years ago and whilst visiting ruins near Umm Qais, up by the Sea of Galilee, my phone was switching to Israeli networks. I also know of an Australian startup that was mis-identified as Russian and lost access to a major partner API². That's since resolved, but the point is, forget what you see on police procedurals; identifying the political jurisdiction of a device, whether it's by IP address or any other means, remains an art, not a science, and it's incredibly easy to be wrong.
As for the suggestion that the rest of us remain unaffected; any malware incident in the node ecosystem requires immediate attention and audit from every security team, whether you were the intended target or not. This idiot has cost all of us time and energy.
[1] https://www.theguardian.com/world/2022/mar/09/finland-gps-di...
[2] https://twitter.com/cyclytics/status/1503211938133966851
The truth is that you are the idiot if you only perform audits when someone else announces an incident. You’ve already lost at that point.
It’s nobody else’s fault but yours if you waste time because of your shit policies.
But go on, keep digging an ever deeper hole for yourself with pathetic attempts at shifting blame. It’s absolutely your security teams job to audit all incoming code, rather than blindly trusting stuff from NPM.
Because: we already do routine malware scanning and audit, and review of every changing dependency that we know of, and their transitive dependencies. The scale and frequency of change is one of the reasons to minimise exposure to the fragmented, chaotic shitshow of the node ecosystem.
When there's an incident - and this is most definitely an incident - we have to do more work to verify there was no inadvertent occurrence, that it did not slip through, etc etc.
What's more, one must necessarily download the shit to inspect it, which means you're potentially now holding an unexploded bomb sitting in your developer laptop, for which possibly the only mitigation is that it's sitting inside a container or virtual machine, and one must be careful not to trigger it.
Due to the destruction of trust, we'll also be making an additional effort to remove and replace this and any other package from the same author, and any repository to which they have contributed has to be considered potentially tainted and subject to additional review.
Since you didn't apparently know any of this, I don't think you have any standing to comment on security team procedures.
>This is doubling down with more poorly considered assumptions and demonstrating an overwhelming lack of knowledge about security process
Sorry, but no. I’ve worked in this field for two decades. What you’re describing is meaningless security theatre meant to appease the people paying your salaries.
And for what it’s worth, you started it with the insults and silly appeals to authority.
I’ve also just realised you’re the same nutter who was desperate to prove Bill Woodcock doesn’t have (and I quote) ”basic understanding of DNS”.
Ok, I’m done smacking this particular witless, flailing troll around. Be seeing you.
Bill Woodcock got the technical details utterly wrong. His track record doesn’t matter when he’s spewing out bullshit, it’s still just that.
Just read your comments again https://news.ycombinator.com/item?id=30513375
You were trying to argue that pulling out root nameservers from Russia would be a bad thing because … Roskomnadzor can only restrict access to foreign DNS servers?
And you call me deluded.
Fairly sure you don't know what that phrase means. Whose authority, exactly? I'll appeal to my own, I suppose, but that is because I actually know what I'm talking about.
Definitely sure you don't have anything to say, but are committed to telling people they're stupid because ... you have little else to contribute, and are stuck in a muddy trench of incoherent rage you dug for yourself. Again.
Read our previous conversation, your comments were about Woodcocks background up until you wanted to change the topic entirely to discuss Russian internet censorship. You were completely unable to come up with a coherent technical explanation as to why Bill wasn’t wrong when he said what he did.
> I suppose, but that is because I actually know what I'm talking about.
That’s it. You can’t supply any useful facts, everything that comes out of your mouth is supposed to be the truth because you are an expert.
Yet, your Linkedin makes it pretty clear that you are a nobody. Just a perpetual software developer and occasional low level manager without any real achievements in his life.
I tried very hard to dig a fact based argument out of you, but I think you know very well that you’re defending bad policy.
The idea that declaring an “incident” over something like this is actually necessary, rather than just a move to appease questions from management is completely frivolous. If you were serious about your security posture, you’d be prepared for these events in the first place.
Trusting NPM is inevitably going to get you hacked.
> are stuck in a muddy trench of incoherent rage you dug for yourself. Again.
Read your own comments, they’re the incoherent ramblings of a crackhead.
> Definitely sure you don't have anything to say, but are committed to telling people they're stupid because
Look in the mirror, you were the first person in this conversation to use words like “idiot”. I merely suggested that the word would be better applied to you.
Past explanations here: https://hn.algolia.com/?dateRange=all&page=0&prefix=false&so...
The flamewar itself was bad on both your parts, and you definitely both broke the site guidelines repeatedly (not cool!), and you both should stop posting like that because we ban accounts that keep posting like that.
> 2) Shut down the root nameservers inside Russia. That would make connectivity spotty for many users inside Russia, but mostly regular folks, not government or military users.
That’s just not true. Shutting down root nameservers inside Russia would not make anyones connection spotty in any meaningful way.
How would that even work? It’s not like sending root NS queries abroad is a big deal, especially since most people will be using ISP nameservers and have those replies cached anyway.
Also
> In the short-term, this is a bad plan because it would cut the Russian man-on-the-street off from international news and perspectives, leaving them with only what the Russian government chooses to tell them. That's not a great way to decrease Russian public support for the war.
This wouldn’t be a consequence of any of the things you listed. International news don’t live on .ru TLD, they don’t depend on domestic root nameservers or Russian IP allocations either.
I wish I was even joking.
At this point I tend to avoid importing anything if I can. I’ve written lots of stuff recently using Go and no imported packages because I trust the vendor more than I trust an open source package repo with 10,000 unknown contributors and dependencies.
Limit your number of (transitive) dependencies, to lower the risk. Yes, this often needs more work on your side.
Use a curated package repository such as Debian/Ubuntu or Fedora (or a repository your company maintains), and only use dependencies from there. Yes, this is very painful for ecosystems that are still moving fast such as JS/Go/Rust, because many packages are not available yet, and non-security updates are less frequent.
This is not really a viable solution in the JS ecosystem if you're using any popular framework like Vue or React. Note Vue pulled in node-ipc.
This "malicious actor" problem can be solved by NPM if they allowed better options when deciding which dependency version to pull. Right now it will pull any semver compatible version the moment it is published - there is no way to say "wait until all versions are at least a week or two old", which would basically eliminate most of the effects of nefarious versions.
Then you may need to reconsider using this kind of framework. If enough people do it, they may have to be more careful about what dependencies they have themselves.
It seems that in the past 2 years people became more pissed about the current state of things than normal. Since fakerjs incident I no longer trust maintainers by default.
You know how some people get very funny in the head discussing politics? This seems to be entering the field of programming bit by bit after programmers slowly realized they are the ones who shape the world. Some people don't know how to handle that level of responsibility so they see 'contributing' as a means to having a lot of power so that when something pokes them wrong they can unleash all their anger and it's not on a 140-character tweet that does nothing and instead it is on all the companies they managed to hold ransom over the free work he was going over the time people were treating him right.
I think this is an equally bad idea. The supply-chain attacks make the news, but getting pwned because of a known vuln in some dependency is a regular occurrence. That 10 year old OpenSSL binary is bad news.
It is hard.
* Minimize dependencies. This is a problem for small organizations that really don't want to rewrite the world.
* Encourage dependencies on organizations that you have trust relationships or contractual relationships with. It is way less likely (though not impossible) that some malicious code will end up in an apache package than some random npm package owned by an individual person.
* Audit dependency changes. At the very least, have systems that detect various known-dangerous APIs showing up in OSS dependencies.
* Make it somebody's job to keep 3rd party code in check. This means pulling updates, auditing updates, and retiring unnecessary dependencies. People at your company should be able to get promoted by saying "we reduced the number of warranty-free dependencies in our codebase by 50%."
Anything short of literally killing Russians, including a embargo is fair game.
Disagree? Go explain it to the Ukrainian father burying his daughter. I don't want to hear it.
This idea that since some people in a country support its foreign misadventures they're fair game is the exact same reasoning employed by Osama bin Laden in his infamous Letter to America: https://www.theguardian.com/world/2002/nov/24/theobserver
On top of that, if there is anybody on the planet I would even entertain that kind of argument/"activism" from, it would definitely not be somebody from the US.
It would be (in my opinion) a fascinating court case to sue a company which got hacked which used lots of OSS, which all had a warranty that says "may not be fit for purpose".
If you built a house out of wood labelled "no warranty, may not be fit for purpose", and it fell down, I imagine you would be held responsible.
How would that be enforced though? Most companies aren't going to be ok making outside connections to the wider internet to check that their JSON de-serializing package can be used.
At the other end of the enforcement spectrums is an enterprise-y place like Oracle and their army of lawyers. They may not be popular, but developer goodwill doesn't pay the bills, paying customers do. Sun never learned that lesson.
At the end of the day, if it's useful enough, IT can make a hole in the firewall. Just look at Splunk.
Short-term: The only way out of this is to review + whitelist every package before it hits the NPM registry. This is something my company is building and we did a write up about it (and Node-ipc) here[0].
Longer term answer: Something like Deno needs to take off that adds permissions per dependency. We need to sandbox all untrusted code by default.
Was it a question of being too soon? Was it horribly un-ergonomic (this is the explanation I usually hear)? Did its features not actually match what developers need?
It feels like callstack based permissions are a natural solution to "holy shit my json deserialization code is deleting files on disk" but there clearly is some trap hidden here that caused old solutions to fail.
Consumer-side: multi-party review prior to upgrades of dependencies in applications.
(note that neither of these necessarily require knowing the identity of the software author(s). in fact, perhaps reviews would be less biased in the absence of that information)
Only auto-upgrade for security fixes. For all others, wait between month to a year to update a dependency, unless one specifically fixes a bug you are experiencing.
Paid subscription-based NPM ? Yes, you could download a dependency directly from the repository on Github for free, but if do so through the paid NPM they assure you that the package is malware-free.
Being a dick includes - but is not limited to - the following instances:
(...)
1c. Modifying the original work to contain hidden harmful content. That would make you a PROPER dick.
By the terms of its original license, I think we can therefore assert that the author is, indeed, a proper dick.[2] https://github.com/RIAEvangelist/node-ipc/commit/9a1ad86d17a...
So the message they are apparently sending here is that means that it's totally OK to host malware on GitHub, given that it's targeted against a politically unpopular group of people, and if you later revert the change after it's done a bunch of damage.
Are some of those Russian developers assholes who support the Ukrainian genocide? Probably yes, but it's an extremely bad precedent to set to allow someone to use your platform for this just because it's politically fashionable.
And yes, I know that there are other things that other people might consider "malware" on GitHub under an overbroad definition of it (exploit PoCs, things like yt-dl, etc.), but this is pretty clear cut, since it hid this "feature" from users and very clearly caused destruction. Either the developer is incompetent at writing obfuscated code and the wiping functionality was a mistake (unlikely), or they are just that dishonest about what their motives actually were. Or just plain delusions of grandeur, equating cyberwarfare with peace...
Apparently though, it's all OK in this instance since it's collective punishment against the right group of people. I think the thing that makes me most angry about this is that the malware developer used the assumption that geo-ip databases are always 100% accurate...
EDIT: looks like Notepad++ also made a political statement about the crisis in Ukraine[2].
[0]: https://github.com/RIAEvangelist/node-ipc/issues?q=is%3Aissu... [1]: https://news.ycombinator.com/item?id=21400526 [2]: https://notepad-plus-plus.org/news/v833-make-apps-not-war/
Also if you're going to delete my comments just delete my account. I'm done ignoring my industry will gladly enable dictators and pretending we are neutral. We are complicit and we need to take a stand... Or maybe we all just want to collect our fat paychecks while inventing more ways to kill people. Shrug.
I could see someone on the right pulling a stunt like this if there was an equal representation of conservative coders in the OSS community.
I am not sure if it could be viable business model though. People who use open source got used that it is free and are unlikely to pay.