colinmcd

Joined 13 years ago

Karma
1,428
Submissions
219
Member since
Aug 27
Creator of Zod Formerly at EdgeDB and Bun Ride-or-die TypeScripter
View on Hacker News

Recent submissions

Comment · 19 days ago
Those are autogenerated release notes that list all commits in the diff. The bad commits were reverted before publication.
Comment · 19 days ago
Comment · 19 days ago
Zod maintainer here. As others have noted, this was three weeks ago and no malware was shipped in any release.

Zod's releasing CI was never triggered and it was not vulnerable to this kind of attack. It uses environment-scoped trusted publishing, so a regular push credential is not enough to trigger releasing. There's a security writeup from the NPM team here[0], though it strongly implies that malicious versions of Zod and Standard Schema were caught by their malware scanner. That's not the case. The attacker was not able of triggering Zod's release CI in the first place. I clarified this in my followup comment[1] and asked them to pick more accurate wording to avoid unnecessary FUD like this.

It seems like a git push credential, probably an SSH key, was exfiltrated from my local computer. The attacker used this to try to push malicious versions of Zod, Standard Schema, and nub. The release workflows for Zod and Standard Schema were not vulnerable against this. (Nub was, however, a release run was triggered, and npm's malware detector did flag it and prevent publication.)

It seemed shady to scrub the commits from history, and it still isn't obvious that doing so is better from a security standpoint. But since there are concerns around git bisect, etc, I've done so anyway. v4.6.6 will lose provenance, v4.6.7 is being released.

Since I don't know exactly what else what compromised, I've also done a fresh OS re-install and rotated all creds present on the old machine at the time of the compromise. All my packages have been switched over to staged publishing, which requires 2FA for any release.

Ironically this likely happened due to some work on an OS-level sandbox for Nub's package manager, designed to limit the blast radius of malicious lifecycle scripts. The attack is consistent with an more primitive precursor to the modern Shai-Hulud-style worms. While working on the sandbox, an ersatz agent likely executed a compromised version of some package on npm in a test run. I had safeguards against this (filtering out any OSV-flagged packages, etc) but perhaps there's an undiscovered malicious package. Future work on this feature will happen on an isolated VM.

[0] https://github.com/orgs/community/discussions/208477

[1] https://github.com/orgs/community/discussions/208477#discuss...

Comment · 4 months ago
Comment · 4 months ago
Comment · 4 months ago
Indeed, Nub intentionally introduces no Nub-specific APIs: no Nub global, no nub: prefixed built-in modules, no Nub-named config file / lockfile, no "nub" field in package.json, not even any NUB_ environment variables. Most of the stuff Bun added is better as a proper dependency imo.
Comment · 4 months ago
Comment · 4 months ago
EDIT: Sorry, I understand you're talking about package.json. Would be fun to try to get the Node & package mgmt teams aligned to add support for comments in the package.json. Bun tried and failed to do this (requires ecosystem coordination).

Nub could absolutely support a config file and use it to set NODE_OPTIONS or flags in the node child process. There's no reason to throw out the baby with the bathwater due to DX concerns like this. That's a key part of the concept Nub is trying to prove. (To be clear I'm quite content to conform to Node's no-config-file policy at the moment.)

Comment · 4 months ago
I almost called it "oi" but I'm not sure anyone would have gotten the joke :P
Comment · 4 months ago
Right now, you should use Nub on the backend if you are relying on its augmentations. If you specifically want to disable Nub's augmentations (so you have a guarantee that your app/script will "just work" with regular Node, there's a couple ways to disable it.

  NODE_COMPAT=0 nub index.ts
  nub --node index.ts

I'll investigate a `nub build` that would do the transpilation upfront and properly chunk/bundle a prod build. It's a good idea. But yes, Nub's overhead (both time and space) is generally negligible relative to Node itself.

Re: added attack surface: the most obvious one is that Nub loads .env files (same as Bun/Next/Vite) so be aware of that. All of Node's permission flags are passed through as well. I won't claim there's no additional attack surface, but it doesn't have much surface area, just a Rust wrapper that spawns `node` ultimately.

Comment · 4 months ago
We use this to register our preload purely for performance reasons. In this and many other cases CommonJS is still faster than ESM. Using --require is about 0.5ms overhead vs 4.6ms for --import (on my M1 Macbook Pro).

Relatedly Node.js recently (2025) introduced a synchronous version of its resolver hook registration API (`module.registerHooks()`) specifically to improve performance over the old async `module.register()` API. It was a big unblocker for Nub. For the interested, the async API added 19ms fixed registration overhead + about 130us additional overhead per import.

Which flag Nub uses here doesn't impact userland at all, TLA is supported wherever it's supported by Node.js itself.

Comment · 4 months ago
It entered public beta last week, but just getting on HN now.

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton