Context: @substack 1 deleted his github account, which includes a lot of foundational source code from the early days of node. The speculation (and it is only speculation as far as I know, though with some foundation in his tweets) is that he did so because of the MFA requirements being imposed on some NPM package maintainers.
Here’s my take. It’s not very hot and is probably marginally more informed than many, but it’s also probably worth what you paid for it. I started writing it as a series of tweets, which is why there are some extremely terse phrasings here.
Companies freeloading off of open source are worried about intentional security compromises in the software they’re benefitting from. Let’s walk through their threat model: Somebody gets access to the account of somebody who works on a package that company X uses and uses that access to publish a deliberate compromise. The update gets taken automatically by the downstream consumer, and then they are shipping their environment variables out to a third party, or running a cryptocurrrency miner, or allowing an attacker to get shell access.
Does forcing maintainers of “important” packages to enable MFA and never turn it off help protect companies from this threat?
Kinda. Restrictions on package authors protect against one category of supply chain attacks. They protect against account hijacking. The state of the world used to be that some NPM users with critical spots in the dependency graph had passwords like “password”. No, I’m not joking. Taking away that easy attack vector seems helpful, so I’m glad we shipped what we did when we did. One good design choice we made was to not implement MFA via SMS, which would have been no protection at all against these threats because social engineering makes SMS not secure at all.
Requiring that a maintainer enable MFA for their account does not, however, protect the source you use from all supply-chain attacks. Legit maintainers have been responsible for some of the worst. Case in point: the infamous left-pad deletion was done by the package maintainer and MFA would not have helped one bit.
MFA is still a good thing to do, but it’s not protection against what the companies freeloading on open source maintainers are worried about.
Why not? Because the account level is only a proxy for the level you care about. You’re far more interested in audit trails that are at the package level and then at the source level. What changed in this release? Did maintainers change? What source changed?
An historical aside
@isntitvacant did think about MFA from the package perspective when he designed the back end support for this! He also thought about restricting tokens to CIDR ranges, though I don’t know if that has ever been exposed. We missed the chance to go even finer-grained on access token permissions than we did. And we definitely should have done audit logs on package ownership changes.
My only excuse is that at the time it felt like a triumph to be able to get the feature shipped at all.
A side comment about the mess we’re in: NPM was designed to maximize engagement from publishers, not to be a good package manager at the scale that it reached. It was designed deliberately to be viral, not to be secure or auditable.
For example: The default being to take updates without thinking about them, for instance, to the point where bots do all that work of dependency updating for you. Downloads number gotta go up.
For example: The tarball as unit of deploy: huge, contains weird stuff that you don’t care about plus whatever silly things the package maintainer put in, hides the deltas. But it was very easy to implement and good enough.2
NPM’s design pushes you into not thinking about your software supply chain by design decisions made when winning a war among competing node package managers was important to somebody.
Stop being pushed. Stop taking updates by default. Think about your supply chain differently.
Problems not proxies
What are you interested in when thinking about this threat? The source itself. The software you’re relying on.
Inspectable audit trails for changes are far more interesting, and this is not something requiring MFA for package maintainers gets you. Looking at maintainers is looking at a proxy for the threat, not the threat itself.
Protecting against the proxy does not give you a free pass on looking at the source you’re depending on and deciding it’s okay. It does not give you a free pass to take every update there is without thinking.
Questions it helps to know the answers to:
- Who published this?
- How do you know they were that person? (Same as controller of repo? Controller of other accounts? What’s the web of identity?)
- What was the chain of control of the source?
- Is the source that was published the same as the source in the advertised repo?
- What was the source delta from the last publication?
- What does the source do?
And given the possibilities of bugs and of some maintainer with bad goals playing the long game, only the questions about the source are on target. The rest are proxies.
The tech industry relies on software they do not take the time to inspect, written by strangers they mostly choose not to pay. Sometimes the industry pays people to work on very critical projects, such as Linux itself! But the web dev world rarely stops to pay the people who were around the node scene at the beginning, writing tiny modules because that was their philosophy, which then got bricked together without their participation into the foundations of modern web development.
Because tech industry companies still don’t want to pay for the work they build on top of–with either their time or their money–they impose requirements on those strangers to attempt to protect themselves from a proxy for the threat, with zero cost to themselves. Those strangers have every right not to participate; it wasn’t what they signed up for back then. Any access to their work you had was a gift.
tl;dr Use Feross’s Socket to scan the source itself; you won’t catch them all; pay people to write any software you truly rely on.
substack the good human, not substack the objectionable paid newsletter company. ↩︎
The tarball is a case of worse is better. And yes, that’s a complex statement itself. It was good enough and easy enough to implement that it satisfied the true requirements of the problem in the moment. Knowing the problem space as well as I do now, and in the current package manager landscape, I would design it quite differently were I to take on the project myself, today. ↩︎