Top
Best
New

Posted by tosh 4 days ago

DuckDB NPM packages 1.3.3 and 1.29.2 compromised with malware(github.com)
390 points | 283 commentspage 2
lovehashbrowns 4 days ago|
I guess it's hands off the npm jar for a week or three 'cause I am expecting a bunch more packages to be affected at this point.
dang 4 days ago||
Related. Others?

We all dodged a bullet - https://news.ycombinator.com/item?id=45183029 - Sept 2025 (273 comments)

NPM debug and chalk packages compromised - https://news.ycombinator.com/item?id=45169657 - Sept 2025 (719 comments)

theanonymousone 4 days ago||
How do these things mostly happen for npm? Why not (much) PyPI or Maven? Or do they?
zahlman 3 days ago||
Python has a heavy standard library, and the most popular third-party libraries tend to have simple dependency graphs because they can lean on that standard library so much. Many of them are also maintained under umbrellas such as the Python Software Foundation (for things like `requests`) or the Python Packaging Authority (for build tools etc.). So there are many eyes on everything all the time, those eyes mostly belong to security-conscious people, and they all get to talk to each other quite a bit.

PyPI also now requires 2FA for everyone and makes other proactive attempts to hunt down malware (https://blog.pypi.org/posts/2023-05-25-securing-pypi-with-2f...) in addition to responding to reports.

There was still a known compromise recently: https://blog.pypi.org/posts/2025-07-31-incident-report-phish... (`num2words` gets millions of monthly downloads, but still for example two orders of magnitude less than NumPy). Speaking of the communication I mentioned in the first paragraph, one of the first people reporting seeing the phishing email was a CPython core developer.

Malware also still does get through regularly, in the form of people just uploading it. But there are automated measures against typo-squatting (you can't register a name that's too similar to existing names, or which is otherwise blacklisted) and for most random crap there's usually just no reason anyone would find out about it to install it.

johnisgood 4 days ago||
Or Cargo. I compiled Zed with release mode, pulled in 2000 dependencies. It does not fill me with confidence.
hu3 4 days ago||
On a related note, the maintainer of the compromised npm packages, debug and chalk, who got pawned, is creating an operational system in rust.

https://github.com/oro-os

https://news.ycombinator.com/user?id=junon

johnisgood 4 days ago||
Good to know! Hopefully others will be delighted to see, too.

I wonder if it really is only npm that got compromised.

xyst 3 days ago||
> ... One of the maintainers read through this text and found it somewhat reasonable. He followed the link (now defunct) to a website hosted under the domain npmjs.help. This website contained a pixel-perfect copy of the npmjs.com website. He logged in using the duckdb_admin user and password, followed by 2FA. Again, the user profile, settings etc. were a perfect copy of the npmjs.com website including all user data. As requested by the email, he then re-set the 2FA setup.

This is absolutely wild that this did not raise _any_ red flags to this person.

red flag: random reset for 2FA ??? red flag: npmjs.help ??? red flag: user name and password not autofilled by browser ??? red flag: copy and pasting u/p combo into phishing site

If _developers_ can't even get this right. Why do we expect dumb users to get this right? We are so cooked.

koakuma-chan 4 days ago||
Should enforce passkeys not 2FA
nodesocket 4 days ago||
I think just supporting yubikeys is sufficient.
KevinMS 4 days ago|||
yubikeys locks up my firefox on both windows and mac, no thanks
nodesocket 4 days ago||
Mine works flawlessly in Chrome on MacOS. Maybe you got defective one, or try factory resetting it.
KevinMS 2 days ago||
a defective one that works fine in all other browsers?
koakuma-chan 4 days ago|||
I have two yubikeys lying around, how do I use them? I don't even have the correct hole in my laptop or in my phone to insert them
egorfine 4 days ago|||
It goes into the square hole.
nodesocket 4 days ago||||
This is a joke right? Can’t say I’ve ever heard of USB ports referred to as “holes”.
koakuma-chan 4 days ago|||
> Can’t say I’ve ever heard of USB ports referred to as “holes”.

I cannot be bother to remember every hole name. They're all USB anyway, the difference is that some are A, C, or Lightning, I bought a new MacBook and it has that magnet hole, what is that called? I'm not following.

SOLAR_FIELDS 4 days ago||
Are you not around hardware that much? This is stuff people who work in tech deal with every day, it's too hard to keep track of the names of the three different ports that you use ubiquitously? When someone asks you what charging port you need, do you just say "big square one" or "the iphone one"? Do you then have to clarify "the old iphone one, not the new one"?
koakuma-chan 4 days ago||
> This is stuff people who work in tech deal with every day

The stuff I deal with every day is centering divs

> it's too hard to keep track of the names of the three different ports

it's more than three ports.

koakuma-chan 4 days ago||
Also USB A is not even square, it's a rectangle
SOLAR_FIELDS 4 days ago||
Point still stands. Maybe it’s 5 if we are being charitable. Do you also call skillets “flat pan thing I cook with”?
khc 3 days ago|||
not being a native English speaker, I actually do this all the time
koakuma-chan 4 days ago|||
You mean frying pan?
koakuma-chan 4 days ago|||
No I'm serious. I used to work on a PC and I had the correct hole, but I never figured out how to make yubikey useful and of course I couldn't use it with my phone. Maybe I'm missing something?
Semaphor 4 days ago||
If it supports NFC, you can use that (mine do, I use them on my phone), otherwise you’d need an adapter, which is clunky but workable.
BenjiWiebe 4 days ago|||
You can use an adapter (usb-a to usb-c). Or are they NFC capable? Some models are.
cr125rider 4 days ago||
How is that different?
semiquaver 4 days ago|||
Passkeys are unphishable because there is nothing to type in. And they are locked to an origin by design, so you can’t accidentally use one on the wrong domain because the browser simply won’t do it.
jve 4 days ago||
... and they are not transferrable, tied to BigCorp & Friends.
Semaphor 4 days ago|||
I use a hardware key as passkey where supported, nothing ties me to anything but those keys. Also there are OSS software managers that support them, like KeePass and friends.
wavemode 4 days ago||
does your hardware key work on mobile? or do you now need to maintain two keys for every service?
vel0city 4 days ago|||
Yes, my hardware keys work on my mobile devices as well.

> do you now need to maintain two keys for every service?

I do maintain multiple keys for every service. I wouldn't say it's a lot of maintenance, any more than a far more secure "remember me" box is "maintenance".

When I register for a new service, I add my hardware token on my keychain as a passkey. I sign in on my laptop for the first time for a service I'll use there more than once, I make a passkey. I sign in on my desktop for the first time, I make a passkey, maybe make a spare in my password manager. Maybe if it's something I use on my phone, I'll make a passkey there as well when I sign in for the first time. When I get around to it, I'll add the spare hardware token I keep in a drawer. But its not like "I just signed up for a new service, now I must go around to every device and make a new passkey immediately. As long as I've got a couple of passkeys at registration time, I'm probably fine.

Lose my laptop? Its ok, I've got other passkeys. Lose my keys? Its ok, I've got other passkeys. My laptop and keys get stolen at the same time? Its ok, I've got other passkeys.

Its really not that hard.

Semaphor 3 days ago|||
> does your hardware key work on mobile?

Yes, they support NFC

> or do you now need to maintain two keys for every service?

I maintain 4 keys so I have backups. In most cases registering additional keys is no problem, and this is only needed when signing up.

udev4096 4 days ago|||
It is on majority of selfhosted pw managers. Vaultwarden, most popular, can transfer passkeys
koakuma-chan 4 days ago||||
Passkey only works when you're on the correct website
diggan 4 days ago|||
Use a password manager (that isn't too buggy and/or suck) and you get the same thing for both TOTP and passwords.
ApolloFortyNine 4 days ago|||
As mentioned elsewhere in this thread, the password manager failing to autofill is hardly unheard of.
diggan 4 days ago||
As also mentioned elsewhere in this submission, it doesn't matter how often autofill breaks/works. There are two cases where it breaks: The accounts not showing up in the password manager modal, and the website autofill not working. The first is what prevents phishing, the second doesn't really matter to prevent phishing or not.

The idea is that if your password manager doesn't show the usual list of accounts (regardless if the actual autofill after clicking the account works or not), you double-check the domain.

yawaramin 3 days ago||
Yes, the idea you are presenting is that the human being must manually check for mistakes. As should be clear by now, this idea does not work at scale. Passkeys will automate and enforce the check, removing human error from the equation.
diggan 3 days ago||
> Yes, the idea you are presenting is that the human being must manually check for mistakes.

Not at all? The password manager handles that automatically, have you never used a password manager before?

> Passkeys will automate and enforce the check

What happens to the passkey when the origin changes, is it automatically recognising it as the new domain without any manual input? Curious to see what magic is responsible for that

yawaramin 3 days ago||
> Not at all?

Yes: '...you double-check the domain.' That's manually checking for mistakes.

> What happens to the passkey when the origin changes,

The passkey won't work at all. You will just have to create a new one.

diggan 3 days ago||
> Yes: '...you double-check the domain.' That's manually checking for mistakes.

Yes, but that's only when the origin changed compared to when you added it to the password manager. Same thing for Passkeys, won't work if the origin is different, so you double-check that the domain in your browser address bar is the correct one.

Obviously normally you don't do anything except click on the account that shows up, since the domain matches.

yawaramin 2 days ago||
With passkeys there is nothing to check manually. If it works, you know it's the domain you registered on. If it doesn't work, you log in with a non-phishable auth method like emailed magic link, then register a new passkey.

You could claim that a phishing site could set up their own passkey registration system–but that still wouldn't give them access to the target's real account.

diggan 2 days ago||
> With passkeys there is nothing to check manually. If it works, you know it's the domain you registered on. If it doesn't work,

So exactly the same as password managers, there is no functional difference if you were using a password manager...

koakuma-chan 4 days ago|||
Npm can't force people to use password manager
diggan 4 days ago|||
Nor does TOTP+password lock you to one authentication provider indefinitely. Tradeoffs :)
maltee 4 days ago|||
You can always register a new passkey with the site if you want to switch authentication providers, can’t you?
diggan 4 days ago||
Yeah, I guess that'd work if I had a couple of accounts, but since there a bunch of them, I really need proper import/export to feel comfortable with moving to it. I just know I'd punt the task of migrating everything if I have to go account-by-account to migrate away.

Considering that today it'd add work for me today, and future work, with no additional security benefits compared to my current approach, it just don't seem worth it.

vel0city 4 days ago|||
I've got passkeys from multiple "authentication providers" available on all of my devices. This isn't a tradeoff.
ljlolel 4 days ago|||
You can if you just force passwords longer than people can memorize or even want to write down (assigned 24+ characters)
koakuma-chan 4 days ago|||
It's just gonna be on a sticky note hanging on the screen or under keyboard
hu3 4 days ago|||
careless people just copy paste those
243423443 4 days ago||||
Care to explain?
vladvasiliu 4 days ago||
The actual URL in the browser is part of what the passkey signs. So if you go to totallynotascam.com which turns out to be some dude intercepting and passing the connection to npm, the signature would be refused by npm since it wouldn't be for the correct domain.
codedokode 4 days ago|||
Unlike humans.
operator-name 4 days ago|||
The browser ensures that a passkey can only be used on the correct site.
ritcgab 4 days ago||
For critical infra projects like this, making a release should require at least three signatures from different maintainers. In fact, I am surprised that this is not a common practice.
feross 4 days ago||
Disclosure: I'm the founder of https://socket.dev.

A few concrete datapoints from our analysis of this incident that may help cut through the hand-waving:

1. This is the same campaign that hit Qix yesterday (https://socket.dev/blog/npm-author-qix-compromised-in-major-...). The injected payload is byte-for-byte behaviorally identical. It hooks fetch, XMLHttpRequest, and common wallet provider APIs and live-rewrites transaction payloads to attacker addresses across ETH, BTC, SOL, TRX, LTC, BCH. One tell: a bundle of very distinctive regexes for chain address formats, including multiple Solana and Litecoin variants.

2. Affected versions and timing (UTC) that we verified:

- duckdb@1.3.3 at 01:13

- @duckdb/duckdb-wasm@1.29.2 at 01:11

- @duckdb/node-api@1.3.3 at 01:12

- @duckdb/node-bindings@1.3.3 at 01:11

Plus low-reach test shots: prebid@10.9.1, 10.9.2 and @coveops/abi@2.0.1

3. Payout so far looks small. Tracked wallets sum to roughly $600 across chains. That suggests speed of discovery contained damage, not that the approach is harmless.

What would actually move the needle:

=== Registry controls ===

- Make passkeys or FIDO2 mandatory for high-impact publisher accounts. Kill TOTP for those tiers.

- Block publishing for 24 hours after 2FA reset or factor changes. Also block after adding a new automation token unless it is bound by OIDC provenance.

- Require signed provenance on upload for popular packages. Verify via Sigstore-style attestations. Reject if there is no matching VCS tag.

- Quarantine new versions from being treated as “latest” for automation for N hours. Exact-version installs still work. This alone cuts the blast radius of a hijack.

=== Team controls ===

- Do not copy-paste secrets or 2FA. Use autofill and origin-bound WebAuthn.

- Require maker-checker on publish for org-owned high-reach packages. CI must only build from a signed tag by an allowed releaser.

- Pin and lock. Use `npm ci`. Consider an internal proxy that quarantines new upstream versions for review.

=== Detection ===

- Static heuristics catch this family fast. Wallet address regex clusters and network shims inside non-crypto packages are a huge tell. If your tooling sees that in a data engine or UI lib, fail the build.

Lastly, yes, training helps, but the durable fix is making the easy path the safe path.

udev4096 4 days ago||
> This website contained a pixel-perfect copy of the npmjs.com website

This should not be considered high effort or a sophisticated attack. The attacker probably used a mitm proxy which can easily replicate every part of your site, with very little initial configuration. Evilginx is the most popular one I could think of

ptrl600 4 days ago||
Is there a way to configure npm that it only installs packages that are, like, a week old?
feross 4 days ago||
Disclosure: I’m the founder of https://socket.dev

A week waiting period would not be enough. On average, npm malware lingers on the registry for 209 days before it's finally reported and removed.

Source: https://arxiv.org/abs/2005.09535

ptrl600 3 days ago||
OK, a week for popular packages, anything else I'd manually review each update. It'd be a nice feature.
HatchedLake721 4 days ago||
Don’t auto install latest versions, pick a version up to a patch and use package-lock.json
mdaniel 4 days ago||
That's only half the story, as I learned yesterday <https://news.ycombinator.com/item?id=45172213> since even with lock files one must change the verb given to npm/yarn to have them honor the lock file

So, regrettably, we're back to "train users" and all the pitfalls that entails

3np 3 days ago||
More importantly, avoid yarn[0] if you have a choice. They do not have a security posture fitting for 2025. There's way too much assumptions like "helpful" "magic" guessing/inferring what the user "actually wants" to "make things just work". See also: corepack.

[0]: legacy 1.x projects aside

lima 3 days ago|
Using Security Keys/FIDO2 instead of TOTP codes completely solves trivial phishing attacks like this one.
More comments...