Hacker Newsnew | past | comments | ask | show | jobs | submit | drdrey's commentslogin

> A while ago, I collaborated on angulartics2, a shared repository where multiple people still had admin rights. That repo still contained a GitHub Actions secret — a npm token with broad publish rights. This collaborator had access to projects with other people which I believe explains some of the other 40 initial packages that were affected.

> A new Shai-Hulud branch was force pushed to angulartics2 with a malicious github action workflow by a collaborator. The workflow ran immediately on push (did not need review since the collaborator is an admin) and stole the npm token. With the stolen token, the attacker published malicious versions of 20 packages. Many of which are not widely used, however the @ctrl/tinycolor package is downloaded about 2 million times a week.

I still don't get it. An admin on angulartics2 gets hacked, his Github access is used to push a malicious workflow that extracts an npm token. But why would an npm token in angulartics2 have publication rights to tinycolor?


I have admin rights on someone else’s npm repo and I’ve done most of the recent releases. Becoming admin lit a fire under me to fix all of the annoying things and shitty design decisions that have been stuck in the backlog for years so most of the commits are also mine. I don’t want my name on broken code that “works”.

I had just about convinced myself that we should be using a GitHub action to publish packages because there was always the possibility that publishing directly via 2FA, that one (or specifically I) could fuck up and publish something that wasn’t a snapshot of trunk.

But I worried about stuff like this and procrastinated on forcing the issue with the other admins. And it looks like the universe has again rewarded my procrastination. I don’t know what the answer is but giving your credentials to a third party clearly isn’t it.


npm has had support for package-scoped publish tokens (with optional 2FA enforcement) for a few years by now. So in case of compromise, the blast radius would be a single package.

The OP gave the GH repo too broad permissions. There is no good reason for the repo CI workflow to have full access to everything under their account.


I’m using the 2FA tokens, my complaint is that “npm publish” from my own machine has no guarantees of being an exact snapshot of trunk. And a worm could inject code into my system to do the Kernighan exploit.

I think over the last few weeks I have at least talked myself into going back to maintaining multiple user accounts on my laptop to separate personal, open source, and entertainment into separate accounts to reduce the last radius, but the fact is sometimes I like to do two things at once and that will be a pain.


You can get pretty close to guarantees.

Fresh git checkout on prod publish. Run all npm/node commands in ephemeral rootless containers. Only have publish token exposed and injected when you are actually publishing (not on install/build just prior). Separating users like you mentioned doesn't hurt bt doesn't sound like your lower-hanging fruit nor something that would likely save your bacon on its own without other workflow adjustments.

None of this is relatively difficult per se, just a bit extra friction which should be worth it to avoid these kinds of events.


Npm supports one time passwords, and iPhone has builtin support for the protocols that npm uses. Someone’s going to have to pickpocket me to hijack that repo. Hacking my machine with supply chain attacks would be much much easier.

> But why would an npm token in angulartics2 have publication rights to tinycolor?

Imo, this is one of the most classical ways organizations get pwned: That one sin from your youth years ago comes to bite you in the butt.

We also had one of these years ago. It wasn't the modern stack everyone was working to scan and optimize and keep us secure that allowed someone to upload stuff to our servers. It was the editor that had been replaced years and years ago, and it's replacement had also been replaced, the way it was packaged wasn't seen by the build-time security scans, but eventually someone found it with a URL scan. Whoopsie.


Thinking of biology, the reason often given for the disappearance of "unused" genes/base-pairs is that there's a metabolic cost to keeping them around and copying them on every cell division, so they vanish from a form of passive attrition.

I wonder if someday we'll find there's also a more active process, which resembles "remove old shit because it may contain security vulnerabilities."


Sorry if that wasn't clear. This was a token with global publish rights to my npm packages.

I was confused too. Was it your npm token stored in angulartics2 as a Github Actions secret, so it could publish new angulartics2 versions?

Yes, exactly.

Easy sharing, easy to make pages public, good syntax highlighting, decent search.


Elon Musk is not a cofounder of Tesla


According to Elon, he is the "founder" of Tesla.

According to Martin, he is their first major investor.

According to mainstream media, he is the co-founder.

I'd call him the second, but the fanboys would be majorly pissed.



that's academic writing for you


OP thought the redirect was synchronous, not that it would stop the script from executing


No, you're mistaken. Read the other comments under the parent. If it were synchronous then it would have stopped the script from executing, much the way POSIX exec() works. If the OP didn't think that the script would stop, then why would he let execution fall through to code that should not execute ... which he fixed by not letting it fall through?


I see, thanks


not even close to being in the same ballpark


Let me know when you find a memory error or concurrency problem, or really any undefined behavior in any of my code.


> https://github.com/timschmidt/repsnapper/blob/master/src/sha...

That variable is undefined in multiple constructors. Also your code cannot compile in various scenarios. Have a nice day.


It's been 5 days and I'm still laughing about this one. Bravo.


I'm laughing too, that code is 13 years old, committed by hurzl here: https://github.com/timschmidt/repsnapper/commit/5410b5d278a5... and in C++. To be clear, I'd handed off maintainership at least a decade ago. I haven't touched this software in many years. Just noticed the reply.

So this doesn't seem relevant to the conversation about LLMs, Rust, and software quality improvement methods from strict typing to formal verification. It's like a "gotcha!" that didn't land. Sorry.

Please, find some bugs in a project I've touched in the last few years! Looking for things to fix. Please open a github issue from an account linked to your projects next time so I can return the favor :D The bugs are in there, I know they are, but with an LLM and a bit of time to review it's work, it now costs me a few minutes tops to write a test to exclude future cases of the same problem or class of problems. Which is a level of verification beyond what's been allocated time in previous projects, where the tests never got written or very infrequently.

Repsnapper's a great example of that. We didn't have a standardized testing framework we were using across the dozen or so libraries we'd integrated into the app. The original author Kulitorum sort of copied and pasted bits and pieces of code together to write the app originally, without much concern for licenses or origin tracking, so I initiated a line-by-line audit and license verification for the codebase in order to qualify it for inclusion in Fedora and Debian to make 3D printing easier and more available as there were no printing tools shipping in a distro at the time. Integrating new libraries into that codebase was unpleasant, working with the build system in general was not my favorite. Lots of room to screw it up, but it has to be just right to work. I think having llms and a testing framework would have allowed us to evolve the Repsnapper code a lot more safely, and a lot further than we ever managed.

Well, and I can say that pretty safely now that I'm in the process of doing just that with https://github.com/timschmidt/alumina-firmware and https://github.com/timschmidt/alumina-ui and https://github.com/timschmidt/csgrs

They're all still very young, still some things stubbed out, code is gross pending revision and cleanup, but it's basically Repsnapper 3.0 in Rust but this version includes CAD and a motion control firmware and fits in < 4mb. Among them I already have hundreds of tests entirely absent from Repsnapper. Couldn't have written csgrs without them. Probably a lot of redundant tests at this point, as things have changed rapidly. I'm only about 6mo of effort in.


who do you hand the cash to in order to fund a website?


Sending cash via snail mail to buy stuff online exists. While Anna's archive does not support it, it certainly exists.


This is also forbidden by several post offices. In my country it's against the law to send money by mail.


Ok, but now you're not comparing bitcoin to cash but rather to cash+mail, which has many more tracking opportunities.


distributed != decentralized


Seems to be neither.


Dyson Sphere Program and a lot of zachtronics games do that very well


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: