Nuri knowledge

The arrayref supply chain attack, and why your wallet needs no single point of failure

TL;DR: Attackers compromised the account of a well-known Rust library and published a fake version that ran malware on a machine the moment someone built it. The bad version sat online for about 86 minutes, and the library has 245 million downloads. This is one of a wave of supply chain attacks that are getting more frequent and more aggressive. The bigger lesson for anyone whose money depends on software is that the code and the servers between you and your funds are a single point of failure. Nuri is built so that no single compromise, not a compromised app and not a hacked server, exposes the key that controls your bitcoin. Only one key ever sits on the phone. The second share lives with a stateless service. Stealing the money takes both.

Updated 18 minute read Markdown
Open contents

The quick answer

On August 20, 2026, a report came in that a Rust library called proc-macro1 was malicious. The Rust Security Response Team confirmed it within minutes: the crate carried a build script that downloaded and ran a remote payload. Building any project that pulled in the crate was enough to execute it. Nobody had to call any function. The build itself was the trigger.

The real target was arrayref, a small, well-known crate used by a huge number of other projects. Its owner account had been compromised. The attacker published a new version of arrayref that depended on the fake crate, and quietly yanked the old versions so that the build tool would point users at the bad one.

None of this is about Rust specifically. It is about how software gets built: we all rely on thousands of pieces written by other people, and any one of them can be the one that is quietly poisoned. When the thing holding your money is software, that stops being a developer problem and becomes a money problem.

What actually happened

The attacker did not rewrite the library. They added one line: a dependency on proc-macro1, a deliberate misspelling of proc-macro2, one of the most downloaded crates in the entire ecosystem. The fake crate is a genuine copy of the real one, so the build succeeds and the software still works. That is exactly the point. Nothing looks broken. The payload runs before you notice anything at all.

The build script quietly reconstructed the attacker server address from pieces of encoded text, turned off the security check that verifies the server is who it claims to be, and then downloaded a program chosen for your operating system and processor. On Mac and Linux it wrote the file to a temporary folder and launched it in the background. On Windows it wrote a script and started it hidden. The attacker chose all of this to avoid being noticed while the build was happening.

The backdoor that was downloaded is a real piece of malware, not a test. Security researchers who analyzed it found that it phones home, reads your computer name and user, lists your installed programs, and looks through your browser profile for saved logins. It installs itself so it comes back after a restart. It can download and run more code on demand. If the main server goes down, it generates fresh domain names to find a new one.

The malicious versions were deleted quickly: arrayref 0.3.10 was online for about 86 minutes, and the two related crates for about 90 and 107 minutes. The Rust team locked the owner account as a precaution and said they do not believe the author was acting in bad faith. Their computer or login is more likely the part that was compromised. The author of arrayref has been maintaining the crate since 2009.

Wiz, a security company, found that the attacker infrastructure overlaps with recent operations attributed to North Korea, including campaigns against other popular libraries. This was not a one-off by a random script kiddie. It was an organized campaign using a pattern they have used before.

  • Target: arrayref 0.3.10, internment 0.8.7 and append-only-vec 0.1.9, all from one compromised account.
  • Vehicle: a new dependency, proc-macro1, a misspelling of the ubiquitous proc-macro2.
  • Trigger: the build itself. Running cargo build on an affected project executed the payload.
  • Online: 86 to 107 minutes before deletion on 2026-08-20.
  • Scale: arrayref has 245 million downloads and appears in the majority of environments that use Rust.

Why this is the new normal

The arrayref attack feels shocking because it hit a popular, trusted library. But the numbers say it should not. The same class of attack has been running against every major package registry for years, and the rate is climbing.

Vendors that track this report more than a million malicious packages found across npm, PyPI, Maven, NuGet and Hugging Face, with the count of new malicious packages in 2025 up about 75 percent from the year before. The estimated cost of supply chain attacks reached roughly 60 billion dollars in 2025, with projections near 138 billion by 2030. Around 30 percent of data breaches now involve a third party, and the large majority of vulnerabilities in commercial software are found not in the main code but in the dependencies it pulls in.

Two things are making it worse at the same time. First, the tooling that builds and runs software has gotten more complex, so there are more moving parts an attacker can touch. Second, the attackers are using AI to find targets, write the malicious code, and scale the campaign, while the people responsible for reviewing every dependency are mostly unpaid volunteers.

The uncomfortable truth on Hacker News, where the main thread hit 400 points and hundreds of comments, is that developers see this coming. One of the most upvoted observations was that the build tooling runs code on your machine without your consent, so adding a dependency is enough to compromise you before you ever review the code. Another pointed out that the same thing happened with the xz compression library compromise, and nobody can read every small package in the deep dependency tree to prove it is clean.

What developers are saying

The Hacker News discussion was unusually calm and specific, which is usually the sign of an experienced community dealing with a known problem. Here is what kept coming up, in their own words, lightly trimmed.

On why it keeps happening: "Why after many previous supply chain attacks do maintainers of package repositories still allow anyone uploading packages and pushing updates without security audit?" That question was not rhetorical. The follow-up was the real problem: "Who is funding this security audit? Are folks supposed to volunteer their free time?"

On the build tooling: "The problem is that build scripts run automatically without user consent or intervention. Adding a dependency is sufficient to compromise you, before you have a chance to even vet the code." Several people noted that other package managers have controls that Cargo does not, such as allow-listing install scripts and putting a cooldown on brand new dependencies.

On the target: "Developer machines are quite juicy targets. They tend to have all sorts of credentials lying around, so it is often not too difficult to escalate from that to compromising your cloud accounts." That is the real prize in most of these attacks. It is not the one machine. It is everything that machine can reach.

On whether the language matters: "Rust seems barely better than Node in this regard." The counterargument, also widely shared, is that the ecosystem already has audit tools, and several large companies publish audits of the crates they depend on. The gap is that auditing is the exception, not the default.

One detail stood out. Several people asked what the malicious code actually does, and the answer was that nobody could be sure, because the author account was deleted and the malicious releases were wiped from the registry rather than just withdrawn. The attacker cleaned up after themselves. That is a hallmark of an operation that has done this before.

When the code controls the money

Most supply chain attacks target developers and companies, and the damage is stolen credentials, stolen data, or a slow, expensive cleanup. The blast radius is a build server or a corporate account.

A wallet is different. The whole point of the software is to be able to move your money. If the code in that software, or the servers it depends on, can be compromised, then the compromise can go straight to the funds. There is no layer of "oops, we lost some logins" between the attacker and your balance.

This is why the supply chain problem and the self-custody problem are the same problem. Both are about where the key that controls your money actually lives, and whether any single point in the chain, a library, a company, a server, a maintainer, a vendor, can take it.

The single point of failure problem

A single point of failure is simple to define and hard to design away. It is the one component that, if it is compromised or it goes down, means the whole thing fails. For a custodial exchange, it is their servers. If those are breached, or if they simply freeze your account, your money is at their mercy. For a software wallet that derives your key from one secret on your device, it is that one secret. If the app is compromised through a poisoned update, or your device is taken, the secret is exposed.

The reason these designs have a single point of failure is that they are convenient. One place to put the key means one place to sign from and one place to back up. Convenience and safety pull in opposite directions, and most products pick convenience.

There is a better shape. Split the authority to move your money across two or more things that an attacker would have to take together, and make sure none of them holds the whole key by itself. Then no single compromise, a bad library, a hacked server, a stolen phone, a malicious update, wins on its own. The attacker has to succeed twice, in two different places, at the same time. That is the difference between a target and a fortress.

How Nuri removes it

Nuri is built on a split-signature scheme called MuSig2, in the 2-of-2 form that can be expanded to 2-of-3. Two separate shares are needed to sign and move the funds, and no single share can do it alone.

On your phone, only one key ever exists: your own key. It is derived locally from your passkey, the biometric or device credential that unlocks your phone, through a function that turns it into a key. That key is generated on your device and it never leaves it. It is not uploaded, it is not sent to a server to be stored, and it is not baked into the app as something that could be pulled out of a compromised build.

The second share is held by Nuri co-signing service. Here is the part that matters for this story. That service is built to be stateless. It holds the authority to co-sign within the policy you have set for your wallet, but it does not store a copy of your key. There is no vault of user keys on Nuri servers to breach. If the app you run is compromised through a supply chain bug, the attacker gets a compromised app, not your key. If Nuri servers are hacked, the attacker gets a stateless service with no user keys to take. Neither event, alone, exposes the private key.

The result is that the arrayref pattern, a poisoned dependency that runs code at build time, does not translate into a stolen wallet. The key that matters is on the phone, derived from something on the phone, and the second signature piece lives with a service that has nothing to give up. Stealing the money requires two whole shares, and they are in two different places that the attacker would have to reach at once.

The design also keeps an exit. The co-signing arrangement is time limited. After a fixed window, the user has an independent recovery path that does not depend on the co-signer. And if you want even more separation, a hardware wallet can be added as a third share, making it 2-of-3, so that no single device or service, phone or server, holds enough to move your funds.

Wallet models, compared on one question

The comparison that matters is not features. It is what a single breach exposes. Here are four common custody models asked the same question.

Custody models compared, mid-2026
ModelWhere the key livesApp is compromisedProvider server is breachedWhat the attacker needs
Custodial exchangeOn the exchange serversYou cannot move your moneyFunds can be frozen or takenOne thing, the exchange
Single key software walletOne secret on your deviceThe secret can be exposedUsually not in the path, but the app is the riskOne thing, your device secret
MPC with a stored server shareSplit, one share kept on the serverApp can expose share handlingA stored share can be stolenThe stored share plus the device share
Nuri, stateless co-signingOne key on the phone, a stateless share on NuriNo usable key is in the appNo user key is stored to takeTwo whole shares, in two places
  • Not documented means the capability is not part of the described design, not that it can never exist.
  • The Nuri column describes the 2-of-2 model with a stateless co-signer, expandable to 2-of-3 with a hardware backup.
  • No model is immune to every attack. This is a comparison of the single point of failure each one leaves behind.

The small glossary

Supply chain attack
A compromise of a component or dependency that others trust, so the attacker reaches everyone who uses it.
Typosquat
A name that looks like a well-known one with a small spelling change, so it is picked up by mistake. proc-macro1 for proc-macro2.
Build script
Code that runs automatically when a project is built. In Rust it can execute before any of your own code, which is why it is a prime target.
Single point of failure
The one component whose loss or compromise defeats the whole system.
Self-custody
You hold the authority to move your own money, instead of a company holding it for you.
MuSig2
A signature scheme that can split the right to sign across multiple keys, so no single key can move the funds alone.
Stateless
The service does not keep a persistent copy of your key. There is nothing stored that a breach can steal.
Passkey
The biometric or device credential that unlocks your phone, used here to derive your key locally.

Questions people ask

What does this Rust attack have to do with my wallet?

Indirectly, a lot. The lesson is not about Rust. It is that the software between you and your money is built from pieces you do not control, and any one of them can be poisoned. A wallet is software whose job is to move your funds, so a supply chain compromise is a direct risk to that money, not just to a developer machine.

Did this attack hit any wallet or any bitcoin user?

There is no evidence the malicious versions were used to hit any wallet or any individual. The Rust team reported no evidence of actual usage, and no patched version exists because the fix was to delete the bad releases. The risk is the pattern, which applies to any software that depends on third party code, and wallets are high value targets for that pattern.

Does self-custody protect me from supply chain attacks?

It depends on the design. Self-custody means you hold the authority, but if that authority is one key in one place, a single compromise still wins. The protection comes from removing the single point of failure, so that the authority is split and no single component, app, server or device, holds enough on its own.

What should I actually do right now?

For your software, keep dependencies pinned and up to date, and watch for new malicious dependency names after incidents like this. For your money, choose a custody model where one breach does not expose your key. If you use Nuri, there is nothing to do. The design already keeps one key on your phone and a stateless share on our side, so a compromised app or a breached server does not hand an attacker your key.

Does a hardware wallet solve this?

A hardware wallet moves the signing away from the phone and the app, which removes a lot of the app supply chain risk. It is a strong choice. Nuri can use one as a third share in a 2-of-3 setup, which adds separation on top of the stateless co-signing rather than replacing it.

What does stateless mean for the Nuri server?

It means the co-signing service does not store your key. It holds the ability to co-sign within your wallet policy, not a copy of the private key itself. So there is no key vault on Nuri servers for an attacker to breach. The private key is derived on your phone from your passkey and stays there.

If the app is compromised, can an attacker see my balance or send money?

A compromised app can see what the app itself can see, and a malicious update could show false information. But moving your money requires a signature, and the signature needs both shares working together. A stateless co-signer with no stored key cannot produce that signature on its own, and the phone key never leaves the device.

Why would an attacker care about a wallet at all?

Because it is direct money. The arrayref backdoor was built to steal credentials, which can be traded or used to reach more. A wallet key is the most direct credential there is. That is exactly why the single point of failure is the thing to remove. Make the key impossible to get from any one place, and the attacker has to be twice as lucky and twice as coordinated.

What can I do as a developer to protect my builds?

Pin your dependency versions and do not auto-update to a brand new release the day it is published. Many teams wait a few days so that auditors and security firms can look at a new version first. Keep an audit of your dependency tree, and watch for new dependency names appearing after an incident like this one. These steps reduce the window in which a poisoned release can reach you.

How often do attacks like this happen?

More often than the headlines suggest. Vendors tracking package registries count thousands of new malicious packages every quarter, and the number keeps growing year over year. Most never make the news because they are typosquats nobody installs. The ones that make the news, like arrayref, are the ones that hit a popular, trusted package. That is the class of event that matters to anyone whose money depends on software.

Sources and update note

Attack details are as of 2026-08-21 and come from the linked Rust team post, security vendor reports and the Hacker News thread. Statistics are estimates from the linked 2026 industry reports and vary by source. Confirm current numbers before relying on them for a decision.

  1. Rust blog: Supply chain attack on arrayref
  2. The Hacker News: Rust supply chain attack puts build time malware in crates
  3. Wiz: Rust supply chain attack on arrayref, DPRK overlap
  4. Socket: Popular Rust crates compromised
  5. BleepingComputer: Hackers poison arrayref Rust crate
  6. Hacker News: Malicious Rust crate Arrayref runs a build time payload
  7. RustSec advisory RUSTSEC-2026-0260
  8. CVE-2026-77651: arrayref supply chain compromise
  9. AppSec Santa: Supply chain attack statistics 2026

The code can be compromised. The design should still hold.

Supply chain attacks will keep coming, and they will keep getting faster. You cannot stop an attacker from poisoning a library. You can build your money so that the poisoned library, the hacked server and the stolen phone each win nothing on their own. That is what removing the single point of failure is for.