Live data from Hacker News

Bitwarden CLI compromised in ongoing Checkmarx supply chain campaign

socket.dev

401–410 of 458 posts

Re: Bitwarden CLI compromised in ongoing Checkmarx supply chain campaign

#401

Earlier quoted context omitted.

That's because you're mixing things. "Rust the language" isn't the one starting new projects and add new dependencies that have hundreds of dependencies of their own, this is the doing of developers. The developers who built Rust with a focus on safety and security is not the same developers mentioned before.

That's true. But it does seem like a logic result of having no real standard library. That lone fact has kept me away from Rust for real projects, because I don't want to pull in a bunch of defacto-standard-but-not-officially dependencies for simple tasks. That's probably a large contributor to the current state of dependency bloat.

I think there's actually a decent compromise one could make here (not that Rust did, mind), and it's what I'm planning for my own language, in big part to avoid the Rust/NPM/etc situation.

TL;DR, the official libraries are going to be split into three parts:

---

1) `core.*` (or maybe `lang.*` or `$MYLANGUAGE.*` or w/e, you get the point) this is the only part that's "blessed" to be known by the compiler, and in a sense, part of the compiler, not a library. It's stuff like core type definitions, interfaces, that sort of stuff. I may or may not put various intrinsics here too (e.g. bit count or ilog2), but I don't know yet.

Reserved by the compiler; it will not allow you to add custom stuff to it.

There is technically also a "pseudo-package" of `debug.*` ("pseudo" in the sense that you must always use it in the full prefixed form, you can't import it), which is just going to be my version of `__LINE__` and similar. Obviously blessed by compiler by necessity, but think stuff like `debug.file` (`__FILE__`), `debug.line` (`__LINE__`), `debug.compiler.{vendor,version}` (`__GNUC__`, `_MSC_VER`, and friends). `debug` is a keyword, which makes it de-facto non-overridable by users (and also easy for both IDEs and compiler to reason about). Of course I'll provide ways of overriding these, as to not leak file paths to end users in release builds, etc.

(side-note: since I want reproducible builds to be the default, I'm internally debating even having a `debug.build.datetime` or similar ... one idea would be to allow it but require explicitly specifying a datetime [as build option] in such cases, lest it either errors out, or defaults to e.g. 1970-01-01 or 2000-01-01 or whatever for reproducibility)

---

2) `std.*`, which is minimal, 100% portable (to the point where it'd probably even work in embedded [in the microcontroller sense, not "embedded Linux" sense] systems and such --- though those targets are, at least for now, not a primary goal), and basically provides some core tooling.

Unlike #1, this is not special to the compiler ... the `std.*` package is de jure reserved, but that's not actually enforced at a technical level. It's bundled with the language, and included/compiled by default.

As a rule (of thumb, admittedly), code in it needs to be inherently portable, with maybe a few exceptions here or there (e.g. for some very basic I/O, which you kind of need for debugging). Code is also required to have no external (read: native/upstream) dependencies whatsoever (other than maybe libc, libdl, libm, and similar things that are really more part of the OS than any particular library).

All of `std.*` also needs to be trivially sandboxable --- a program using only `core.*` & `std.*` should not be able to, in any way, affect anything outside of whatever the host/parent system told it that it can.

---

3) `etc.*`, which actually work a lot like Rust/Cargo crates or npm packages in the sense that they're not installed by default ..... except that they're officially blessed. They likely will be part of a default source distribution, but not linked to by default (in other words: included with your source download, but you can't use them unless you explicitly specify).

This is much wider in scope, and I'm expecting it to have things like sockets, file I/O (hopefully async, though it's still a bit of a nightmare to make it portable), downloads, etc. External dependencies are allowed here --- to that end, a downloads API could link to libcurl, async I/O could link to libuv, etc.

---

Essentially, `core.*` is the "minimal runtime", `std.*` is roughly a C-esque (in terms of feature count, or at least dependencies) stdlib, and `etc.*` are the Python-esque batteries.

Or to put it differently: `core.*` is the minimum to make the language run/compile, `std.*` is the minimum to make it do something useful, and `etc.*` is the stuff to make common things faster to make. (roughly speaking, since you can always technically reimplement `std.*` and such)

I figured keeping them separate allows me to provide for a "batteries included, but you have to put them in yourself" approach, plus clearly signaling which parts are dependency-free & ultra-sandbox-friendly (which is important for embedding in the Lua/JavaScript sense), plus it allows me to version them independently in cases of security issues (which I expect there to be more of, given the nature of sockets, HTTP downloads, maybe XML handling, etc).

Re: Bitwarden CLI compromised in ongoing Checkmarx supply chain campaign

#403

Earlier quoted context omitted.

Does it matter? The individual researchers could look at brand-new published packages just the same

For researchers who notice new releases as soon as they are published and discover malice based on that alone, I agree, and every step of that can be automated to some level of effectiveness. But for researchers who aren't sufficiently effective until the first victim starts shouting that something went sideways, the malicious actor would be wise to simply ensure no victim is aware until well after the cooldown perio…

Novel obfuscation, with a novel idea, is hard to invent. Novel obfuscation, where it is only new to that codebase, is easy(ier) to flag as suspicious.

While bad actors would be wise to ensure low-cooldown users are unaware, I would not say they can "simply" ensure that.

Code with any obfuscation that evades static analysis should become more suspicious in general. That's a win for users.

A longer window of time for outside researchers is a win for users -- unless the release fixes existing problems.

What we need is allowing the user to easily change from implicitly trusting only the publisher to incorporate third parties. Any of those can be compromised, but users would be better served when a malicious release must either (1) compromise multiple independent parties or (2) compromise the publisher with an exploit undetectable during cooldown.

Any individual user can independently do that now, but it's so incredibly time-consuming that only large organizations even attempt it.

Re: Bitwarden CLI compromised in ongoing Checkmarx supply chain campaign

#404

Anyone know of a better way to protect yourself than setting a min release age on npm/pnpm/yarn/bun/uv (and anything else that supports it)? Setting min-release-age=7 in .npmrc (needs npm 11.10+) would have protected the 334 unlucky people who downloaded the malicious @bitwarden/cli 2026.4.0, published ~19+ hours ago (see https://www.npmjs.com/package/@bitwarden/cli?activeTab=versi... and select "show deprecated vers…

we've been running Renovate with `minimumReleaseAge: '7 days'` across all our repos for a while now, which does basically the same thing across npm, PyPI, and Cargo in one config. the tradeoff is you're always 7 days behind on patches, but for anything touching CI or secrets tooling that feels like a fair deal. the nasty part of this class of attack is the timing window is usually sub-24h before it's pulled, so even 3 days would have caught this one.

Re: Bitwarden CLI compromised in ongoing Checkmarx supply chain campaign

#405

Anyone know of a better way to protect yourself than setting a min release age on npm/pnpm/yarn/bun/uv (and anything else that supports it)? Setting min-release-age=7 in .npmrc (needs npm 11.10+) would have protected the 334 unlucky people who downloaded the malicious @bitwarden/cli 2026.4.0, published ~19+ hours ago (see https://www.npmjs.com/package/@bitwarden/cli?activeTab=versi... and select "show deprecated vers…

Don't write anything backend or cli tool in NPM would be good start

Security by obscurity. If another language became as ubiquitous as JS then it'd be the same.

In the context of TFA, don't rely on third party github actions that you haven't vetted. Most of them aren't needed and you can do the same with a few lines of bash. Which you can also then use locally.

Re: Bitwarden CLI compromised in ongoing Checkmarx supply chain campaign

#406
post #391

Earlier quoted context omitted.

Better for the cool down to be managed guaranteed centrally by the package forge rather than ad-hoc by each individual client.

The cooldown is a defence against malicious actors compromising the release infrastructure. Having the forge control it half-defeats the point; the attackers who gained permission to push a malicious release, might well have also gained permission to mark it as "urgent security hotfix, install immediately 0 cooldown".

I have not heard anyone seriously discuss that cooldown prevents compromise of the forge itself. It’s a concern but not the pressing concern today.

And no, however compromised packages to the forge happens, that is not the same thing as marking “urgent security hotfix” which would require manual approval from the forge maintainers, not an automated process. The only automated process would be a blackout period where automated scanners try to find issues and a cool off period where the release gets progressively to 100% of all projects that depend on it over the course of a few days or a week.

Re: Bitwarden CLI compromised in ongoing Checkmarx supply chain campaign

#407

Earlier quoted context omitted.

"Just" is doing a lot of work; most ecosystems are not set up or equipped to do this kind of server-side queuing in 2026. That's not to say that we shouldn't do this, but nobody has committed the value (in monetary and engineering terms) to realizing it. Perhaps someone should. By contrast, a client-side cooldown doesn't require very much ecosystem or index coordination.

>Perhaps someone should This kind of thinking is why I don't trust the security of open source software. Industry standard security practices don't get implemented because no one is being paid to actually care and they are disconnected from the users due to not making income from them.

Having been in both worlds, I don't think the median unpaid OSS developer is any more (or less) dispassionate about security outcomes than the median paid SWE. There's lots of "maybe someone should do this" in both worlds.

(With that said, I think it also varies by ecosystem. These days, I think I can reasonably assert that Python has extended significant effort to stay ahead of the curve, in part because the open source community around Python has been so willing to adopt changes to their security posture.)

Re: Bitwarden CLI compromised in ongoing Checkmarx supply chain campaign

#408

Earlier quoted context omitted.

'no real standard library' doesn't seem entirely fair. Rust has a huge standard library. What it does have is the policy to only include "mature" things with little expected API evolution in the standard libary, which leaves gaping holes where a json parser, a http client or a logging library should be. Those are all those defacto-standard-but-not-officially dependencies

Perhaps that’s just a sign Rust isn’t suitable for those type of projects.

It's a sign that they learned from Python more than anything else. Better be conservative than have Python's situation of multiple versions of those common functionalities (in the stdlib) that almost nobody uses and goes for 3rd party libraries anyway. Is that a better state of affairs?

The Rust vs. Node comparison seems very shallow to me, and it seems to require a lot of eye squinting to work.

People have beef with Rust in other, more emotional ways, and welcome the opportunity to pretend they dislike it on seemingly-rational grounds a la "Node bad amirite lol".

Re: Bitwarden CLI compromised in ongoing Checkmarx supply chain campaign

#409

Earlier quoted context omitted.

That isn't a smoking gun. I think it was the Vault7 leaks which showed that the NSA and CIA deliberately leave trails like this to obfuscate which nation state did it. I'm sure other state actors do this as well, and it's not a particularly "crazy" technique.

So, Russia is no longer a target for CIA?

What? All I'm saying is that attribution isn't easy to do in these cases.

Re: Bitwarden CLI compromised in ongoing Checkmarx supply chain campaign

#410

Earlier quoted context omitted.

That's because you're mixing things. "Rust the language" isn't the one starting new projects and add new dependencies that have hundreds of dependencies of their own, this is the doing of developers. The developers who built Rust with a focus on safety and security is not the same developers mentioned before.

That's true. But it does seem like a logic result of having no real standard library. That lone fact has kept me away from Rust for real projects, because I don't want to pull in a bunch of defacto-standard-but-not-officially dependencies for simple tasks. That's probably a large contributor to the current state of dependency bloat.

So you only use languages that have a built-in HTTP client, JSON / CSV / XML parsers, and such?
Post reply on HN