3 ms·
Direct link to Code: https://www.lunasec.io/docs/blog/node-ipc-protestware#a-look-at-the-malware-itself https://www.lunasec.io/docs/blog/node-ipc-protestware#a
by freeqaz 5y ago
Direct link to Code:
https://www.lunasec.io/docs/blog/node-ipc-protestware#a-look-at-the-malware-itself https://www.lunasec.io/docs/blog/node-ipc-protestware#a-look...
Edit: I tried to link directly there but it didn't work. The "hash fragment" in my submitted URL doesn't actually make it's way through the Hacker News link filter. My apologies to everybody for having to scroll to the bottom to actually get to the "real code"! Here is the link to use instead up above. (The rest is my OG comment)
------
My colleague and I wanted to understand how this malware/Protestware worked, so we took the time to manually de-obfuscate the code that was bundled with the recent "node-ipc" NPM package to find out.
It's pretty simple and makes it clear that this wasn't very "advanced" malware. It was very much an emotionally motivated Open Source dev wanting to use their "power" to protest the war. The impact of a more sophisticated attack is... something I think about a lot about how to fix.
That's why this is another good reminder to keep thinking about how we can actually "fix" these types of supply-chain attacks. Here is a list of malware in a spreadsheet[0] from other authors that also have protestware bundled. (It's in Russian but the Google Translate browser extension worked for me.)
I wrote a blurb at the bottom of this blog post when we published it talking about mitigating "bad" NPM packages, and I need to update it to add a bit about projects like Deno[1] that are attempting to solve this by "forking" the Node ecosystem.
Deno adds permissions per dependency (like a browser extension or phone app) and sandboxes all untrusted code by default. It's going to take us many years before we're at the point where a project like that is "production ready" but it's something that I'd encourage you to check out!
0: https://docs.google.com/spreadsheets/d/1H3xPB4PgWeFcHjZ7NOPtrcya_Ua4jUolWm-7z9-jSpQ/htmlview?pru=AAABf7z88MA*ITSp0EBrKinw0LjFWZ9tzQ# https://docs.google.com/spreadsheets/d/1H3xPB4PgWeFcHjZ7NOPt...
1: https://deno.land/ https://deno.land/
- dane-pgp 5y ago> Deno adds permissions per dependency Another project heading in that direction is also an anagram of Node: "The foundation of Endo is SES, a tamper-proof JavaScript environment that allows safe execution of arbitrary programs in Compartments. ... Endo uses LavaMoat to automatically generate reviewable policies that determine what capabilities will be distributed to third party dependencies. https://github.com/endojs/endo https://github.com/endojs/endo
- freeqaz 5y agoEdit: Lol, I was looking at my previous submissions to HN and I noticed that I'd submitted[3] LavaMoat just a few weeks ago! Maybe with this recent Protestware stuff going on, that project can get a few more contributors wanting to help out. ------ Nice! Thanks for sharing that link. I've done a bit of digging into that project before and it's definitely a very promising idea. It has a lot of the same pitfalls as Dyno, imo, in that it would require somebody to define a "security policy" for every module to whitelist permissions. But, it's also something that could maybe be attached similarly to how TypeScript types are "retroactively" added for existing vanilla JS NPM packages. Ie, packages that have never added their own type declarations (like `express`) can have their types added to DefinitelyTyped[0] and published as a separate NPM package (`@types/express`). It works fairly well and something like `@endo-policies/express` wouldn't be crazy to add in later. Obviously it's going to be super painful, but fixing tech debt is always going to hurt. vm2[1] is another Node project with some semi-similar goals that's worth mentioning. It's not designed to be "applied" in the same way as Endo, but it does give you a way to "sandbox" dependencies. As a security person, I am weary to trust something like vm2 because it is much harder to "get right" than a "sandboxed-by-default" approach like Endo or Dyno. Look at this[2] CVE on vm2 from a few months ago for some evidence about _why_ this approach isn't ideal. I'm optimistic for the future but we still have a long way to go before we get to it! 0: https://github.com/DefinitelyTyped/DefinitelyTyped https://github.com/DefinitelyTyped/DefinitelyTyped 1: https://www.npmjs.com/package/vm2 https://www.npmjs.com/package/vm2 2: https://github.com/advisories/GHSA-6pw2-5hjv-9pf7 https://github.com/advisories/GHSA-6pw2-5hjv-9pf7 3: https://news.ycombinator.com/item?id=30280642 https://news.ycombinator.com/item?id=30280642
- dane-pgp 5y ago> it would require somebody to define a "security policy" for every module to whitelist permissions. That doesn't seem particularly onerous. The writers of a piece of software should know if it requires network or filesystem or shell or eval access, and adding those permission requests to a package should require just a couple of keywords added to a config file. If the permissions are too strict, then someone running the code in an enforcing runtime will get errors and presumably add an override, then submit a one-line patch upstream. On the other hand, if the permissions aren't strict enough, people should think "Hey, why does this arithmetic library need filesystem access?" and submit one-line patches to remove that permission request. The hardest part will be encouraging writers of popular packages to split them along permission lines, so that people can install just the subset of functionality that solves their use case without granting unnecessary permissions.
- Already__Taken 5y agoyears? we've done it already. run everything in containers. Am I missing something painfully obvious?
- freeqaz 5y agoContainers can help to prevent some attack scenarios, ie by making it easier to "re-deploy" a container that has had all of it's files deleted, but they don't "sandbox" code very effectively against a sophisticated attack. For example: If you install a package that generates a random UUID, and that package has malware added to it silently, that package can do _anything_ that your backend code can do. Would you expect your random UUID library to make a network call out to a server and then open up a Bash shell to let somebody execute arbitrary commands? Containers don't help prevent that scenario. The only way to "fix" that is to _limit_ the default permissions of a library to be something sane. Maybe this UUID library is allowed to have filesystem access to read `/dev/urandom` but not to read `~/.ssh/id_rsa`. The default Node runtime does not provide any mechanism to whitelist or filter what privileges a module requires. Adding that capability would require major changes to the entire ecosystem (like every package adding a "permissions" manifest file).