Worked example · 2023-12
Ledger Connect Kit npm supply-chain compromise — multi-chain (EVM) — 2023-12-14
Summary
Ledger Connect Kit is a JavaScript library published by Ledger SAS as @ledgerhq/connect-kit on npm. The library is embedded by Web3 dApps that wish to allow end-users to connect Ledger hardware wallets to the dApp's signing UI; on first-page-load by any dApp embedding the library, the user-facing signing surface includes code paths from this library. By design the library has access to the wallet-connection and signing UI at a level sufficient to render connection prompts, list available wallets, and pass signing requests to the user's hardware wallet. As of December 2023 the library was embedded across a significant cohort of Web3 dApps including Sushi, Lido, Zapper, Revoke.cash, and others; the public CDN edges (jsDelivr, unpkg) served the library to any user-browser visiting any embedding dApp.
On December 14, 2023, an attacker — using credentials previously belonging to a former Ledger employee whose npm-publish credentials had not been rotated after their departure — published three malicious versions (1.1.5, 1.1.6, 1.1.7) of the library to the npm registry over the compromise window. The malicious versions, once served through the public CDN edges to any embedding dApp's user-browser, replaced the legitimate signing-prompt logic with a wallet-drainer overlay: end-users connecting any wallet (not only Ledger hardware wallets) through any embedding dApp during the compromise window saw a UI prompting them to approve token-transfer / token-allowance operations that, if approved, redirected the user's funds to attacker-controlled addresses.
The proximate cause — per Ledger's own post-incident statement and the corroborating ZachXBT, Blockaid, and SlowMist write-ups — is twofold: (a) operator-side, a former Ledger employee's npm-publish credentials had not been rotated and were reused by the attacker after a phishing compromise of the former employee, and (b) structural, the npm-publish-credential surface for @ledgerhq/connect-kit was protected by username / password authentication only at the time of the incident, without enforced multi-factor authentication on the publish path (Ledger subsequently committed to MFA enforcement on critical-package publish paths as part of the post-incident remediation). The combination of the credential-rotation gap and the publish-path-MFA gap produced the exploitable surface.
For OAK's purposes the case is the canonical 2023 worked example of npm-supply-chain-compromise-affecting-many-dApps — distinct from the contract-level compromise pattern that dominates the OAK-T9 family and from the operator-internal hot-wallet compromise pattern that dominates the OAK-T11 family. The novel OAK contribution of the worked example is documenting the npm-package-as-signing-path dimension explicitly: any dApp embedding @ledgerhq/connect-kit was, structurally, trusting the integrity of every Ledger npm-publish credential and every CDN-edge cache to deliver an unmodified version of the library to its end-users. The compromise window of approximately five hours produced approximately $600K in realised on-chain extraction across the cohort of embedding dApps' end-users — a relatively small per-incident loss figure that understates the structural systemic risk the case illustrates.
Timeline (UTC)
| When | Event | OAK ref |
|---|---|---|
| Pre-event | Former Ledger employee leaves the company; npm-publish credentials not rotated; npm-publish path for @ledgerhq/connect-kit not protected by enforced MFA |
(off-chain entry-vector precondition) |
| Pre-event (days before 2023-12-14) | Former employee receives phishing payload; phishing harvest yields the npm-publish credentials | T11.002 entry-vector precondition (off-chain phishing surface) |
| 2023-12-14 ~13:45 | Attacker publishes malicious version 1.1.5 of @ledgerhq/connect-kit to npm using the harvested former-employee credentials |
T11.002 entry vector |
| 2023-12-14 (within minutes) | Subsequent malicious versions 1.1.6 and 1.1.7 published; all three versions begin propagating through public CDN edges (jsDelivr, unpkg) | T11.002 entry vector continues |
| 2023-12-14 (within minutes of CDN propagation) | Embedding Web3 dApps (Sushi, Lido, Zapper, Revoke.cash, others) begin serving the malicious code to end-user browsers through their embedded connect-kit references; wallet-drainer overlay activates on user signing-prompt surfaces |
T1.003 (compromised front-end) |
| 2023-12-14 (within ~5 hours) | Cumulative extraction across embedding dApps' end-users reaches approximately $600K; on-chain investigators (notably ZachXBT) publicly identify the malicious npm versions | T5-equivalent (extraction event) |
| 2023-12-14 (within ~5 hours of first publish) | Ledger detects the compromise; revokes the malicious versions on npm; publishes a clean version (1.1.8) | (operator response) |
| 2023-12-14 — 2023-12-15 | Embedding dApps update their pinned versions to the clean 1.1.8; CDN edge caches purge the malicious versions | (cohort response) |
| 2023-12-14 onward | Ledger publicly engages Tether and Chainalysis; Tether freezes USDT proceeds on the drainer cluster reachable on Tether-controlled addresses | (operator-led recovery) |
| 2023-12 onward | Ledger publishes detailed post-incident statement; commits to MFA enforcement on critical-package publish paths; affected end-users reimbursed via Ledger / dApp-coordinated programme for non-recoverable funds | (operator response, transparency) |
| 2023-12 onward | Drainer-cluster operator routes proceeds through standard 2023 commercial-drainer laundering rails (Tornado Cash, mixer-rail, drainer-as-a-service shared infrastructure) | T7.001 (off this example's framing) |
| 2024 onward | npm registry-wide MFA-enforcement push (industry response) accelerates in part as a downstream effect of the Ledger Connect Kit case and the late-2023 / 2024 npm-supply-chain-compromise cohort | (cohort mitigation, partial) |
What defenders observed
- The npm dependency-tree is a load-bearing signing-path surface. Every Web3 dApp embedding
@ledgerhq/connect-kitwas, structurally, trusting the integrity of every Ledger npm-publish credential and every CDN-edge cache to deliver an unmodified version of the library to its end-users. The compromise window of approximately five hours produced approximately $600K in realised on-chain extraction; the structural systemic risk is much larger than the realised-loss figure suggests, because the per-incident loss is bounded by the compromise window length, the embedding dApps' user-volume during the window, and the per-user value-at-risk during signing operations, none of which are floors. Defender practice for Web3 dApps should treat the dependency-tree of any package that touches the signing UI as part of the signing-path threat-model. - Credential-rotation discipline on package-publish credentials is a recurring 2023–2024 OAK failure mode. The Ledger case is the canonical 2023 worked example: a former employee's npm-publish credentials had not been rotated after the employee's departure, and were reused by the attacker after a phishing compromise of the former employee. The structural lesson is that the credential-rotation surface for package-publish credentials is operationally distinct from the credential-rotation surface for typical employee SSO / VPN credentials — package-publish credentials often live in CI / build-system contexts and may not be visible to standard offboarding workflows. Defender practice for any organisation publishing critical npm packages should include explicit package-publish credential inventory and rotation discipline as part of offboarding workflows.
- Publish-path MFA enforcement is the load-bearing missing control. At the time of the compromise, the npm-publish path for
@ledgerhq/connect-kitwas protected by username / password authentication only. Even with the former-employee credentials harvested, an MFA challenge on the publish path would have prevented the attacker from publishing the malicious versions. Ledger's post-incident remediation included MFA enforcement on critical-package publish paths; the npm registry's industry-wide push toward enforced MFA on critical packages accelerated in part as a downstream effect of this and similar 2023 / 2024 cases. Defender practice for any organisation publishing npm packages used in signing-path contexts should treat publish-path MFA as a hard control, not as an optional one. - The compromise window is observable to any defender with public CDN visibility. The malicious versions 1.1.5 / 1.1.6 / 1.1.7 were detectable as anomalies by anyone monitoring the publish-history of
@ledgerhq/connect-kitfor unscheduled releases. The version-bump pattern (three rapid version increments in a short window, without corresponding GitHub commits or release notes) was itself a public signal that the publish path had been compromised. Defender practice for Web3 dApps should include automated monitoring of pinned dependency versions for off-pattern publish events, with rollback to a known-good version as the operational response. - Recovery via operator-side stablecoin-issuer engagement is partial but real. Ledger's engagement with Tether produced a partial freeze on the USDT proceeds of the drainer cluster reachable on Tether-controlled addresses. The recovered fraction is material but not majority — the majority of the realised $600K was non-USDT and was already out of operator-reach when the freeze landed. The defender / Mitigations-layer lesson is that operator-side stablecoin-issuer engagement (Tether, Circle for USDC, etc.) is a real recovery primitive on the EVM / Tron rails and should be pre-positioned as part of incident-response runbooks for operators with significant stablecoin exposure to the drained surface.
What this example tells contributors writing future Technique pages
- T11.002 + T1.003 is a discrete chained attack pattern that the Mitigations layer should cover as an integrated unit. The Ledger Connect Kit case is the canonical 2023 worked example. The chain is: T11.002 (npm-package compromise via harvested publish credentials) + T1.003 (compromised front-end through embedded library code). Future contributor guidance should consider a cross-cutting Mitigation entry covering the entire chain rather than two independent Mitigation entries; the chained pattern is operationally distinct enough to warrant integrated coverage. The structural parallel within the corpus is the Curve DNS hijack case at
/examples/2022-08-curve-dns-hijack.md— both cases illustrate that the dApp signing-path surface is wider than the dApp's own code and includes the full chain of distribution dependencies. - The npm-supply-chain-compromise-affecting-many-dApps sub-class deserves explicit framing in the Mitigations layer. Ledger Connect Kit (December 2023) is the canonical worked example. Subsequent cases in the npm-supply-chain cohort (web3 wallet-related package compromises through 2024–2025) extend the pattern; OAK's worked-example layer should cross-reference forward as those cases are added to the corpus. The defender lesson is that any npm package embedded in a signing-path context is a fan-out attack surface — one compromise affects every embedding dApp simultaneously, and the realised-loss-bound is the union of the embedding dApps' end-user value-at-risk during the compromise window, not any single dApp's risk in isolation.
- Credential-rotation discipline on package-publish credentials should be an explicit Mitigations-layer entry. The Ledger case is the cleanest worked example for this dimension. The structural lesson is that package-publish credentials operate in CI / build-system contexts that may not be visible to standard offboarding workflows; defender practice for any organisation publishing critical npm packages should include explicit package-publish credential inventory and rotation discipline.
- Operator-side stablecoin-issuer engagement is a real recovery primitive that should be pre-positioned, not provisioned at incident time. The Ledger case anchors this dimension. The recovered fraction was material but not majority; the recovery primitive activates only when the operator has pre-positioned the relationship with stablecoin issuers (Tether, Circle, etc.) and has the operational capacity to engage within the pre-laundering time window. Defender practice for any operator with significant stablecoin exposure to the user-affected surface should include this primitive in incident-response runbooks.
- Pseudonymous-attribution-of-on-chain-attacker plus partially-named-attribution-of-operator-side-compromise-vector is a recurring 2023–2024 attribution shape and deserves framing. The Ledger case is the cleanest worked example of this combined attribution shape: the on-chain drainer-cluster operator is
pseudonymous(no industry forensics provider has converted the cluster analysis into a named-individual claim), while the operator-side compromise vector ispartially-named(Ledger publicly characterised the vector as a former-employee phishing attack, without naming the former employee). Contributors writing the worked-example layer should preserve the dimension and not collapse the two attribution shapes into a single category.
Public references
[ledgerpostmortem2023]— Ledger official post-incident statement on the December 2023 Connect Kit compromise, including the timeline, the former-employee phishing entry-vector characterisation, and the post-incident remediation commitments (MFA enforcement on critical-package publish paths).[blockaidledger2023]— Blockaid technical analysis of the malicious-versions wallet-drainer overlay and the embedding-dApp impact cohort.[zachxbtledger2023]— ZachXBT public on-chain analysis identifying the malicious npm versions during the compromise window and tracking the drainer-cluster proceeds.[slowmistledger2023]— SlowMist incident analysis covering the npm-supply-chain compromise pattern and the laundering chain through standard 2023 commercial-drainer rails.[matterlabsledger2023]— Industry / community technical write-ups on the malicious-JS analysis and the dApp-side response patterns (pinned-version rollback, CDN-edge cache purge).[chainalysisledger2023]— Chainalysis cohort context for the late-2023 wallet-drainer-as-a-service ecosystem that was the back-end of the Ledger Connect Kit compromise.[npm2024mfa]— npm registry-wide MFA-enforcement push (industry response) accelerated in part as a downstream effect of the Ledger Connect Kit case and the broader late-2023 / 2024 npm-supply-chain-compromise cohort.
Citations
Existing citation keys reused: none directly — this is the first OAK example in the npm-supply-chain-compromise sub-class.
Proposed new BibTeX entries (do NOT add to citations.bib in this task; for contributor review):
@misc{ledgerpostmortem2023,
author = {{Ledger}},
title = {Ledger Connect Kit Exploit: Post-Mortem},
year = {2023},
howpublished = {Operator-side public statement, Ledger blog},
url = {https://www.ledger.com/blog/security-incident-report},
note = {OAK v0.1 — pending verification. Ledger official post-incident statement on the December 2023 Connect Kit compromise; characterises entry vector as former-employee phishing leading to npm-publish credential reuse; commits to MFA enforcement on critical-package publish paths.}
}
@misc{blockaidledger2023,
author = {{Blockaid}},
title = {Ledger Connect Kit Compromise — Technical Analysis of the Wallet-Drainer Payload},
year = {2023},
howpublished = {Industry technical analysis, Blockaid blog},
url = {https://www.blockaid.io/blog/ledger-connect-kit-attack-analysis},
note = {OAK v0.1 — pending verification. Technical analysis of the malicious-versions wallet-drainer overlay payload and the embedding-dApp impact cohort.}
}
@misc{zachxbtledger2023,
author = {{ZachXBT}},
title = {Ledger Connect Kit Malicious Versions and Drainer-Cluster Tracking},
year = {2023},
howpublished = {Public on-chain analysis, X (formerly Twitter)},
url = {https://twitter.com/zachxbt/status/1735314463415070985},
note = {OAK v0.1 — pending verification. ZachXBT public on-chain analysis identifying the malicious npm versions during the compromise window and tracking the drainer-cluster proceeds.}
}
@misc{slowmistledger2023,
author = {{SlowMist}},
title = {Ledger Connect Kit Supply-Chain Attack Analysis},
year = {2023},
howpublished = {Industry incident analysis, SlowMist Inc.},
url = {https://slowmist.medium.com/ledger-connect-kit-supply-chain-attack-2023},
note = {OAK v0.1 — pending verification. SlowMist incident analysis of the npm-supply-chain compromise pattern, the malicious-version timeline, and the laundering chain through 2023 commercial-drainer rails.}
}
@misc{npm2024mfa,
author = {{GitHub} and {npm Registry}},
title = {Mandatory 2FA Enforcement on High-Impact Packages},
year = {2024},
howpublished = {Registry policy update, GitHub / npm blog},
url = {https://github.blog/2022-05-10-enhanced-2fa-experience-for-npm-package-publishers/},
note = {OAK v0.1 — pending verification. npm registry-wide MFA-enforcement push (industry response) accelerated in part as a downstream effect of the Ledger Connect Kit case and the broader late-2023 / 2024 npm-supply-chain-compromise cohort.}
}
Discussion
Ledger Connect Kit (December 2023) is OAK's canonical 2023 worked example for the npm-supply-chain-compromise-affecting-many-dApps sub-class of T11.002, paired with T1.003 as the front-end-compromise extraction surface. The case is operationally instructive precisely because the per-incident realised loss (~$600K) understates the structural systemic risk: the compromise window of approximately five hours produced realised loss bounded by the embedding dApps' end-user value-at-risk during the window, and the same compromise pattern with a longer window or higher-volume embedding dApps would have produced a much larger realised loss. The defender / Mitigations-layer lesson generalises: any npm package embedded in a signing-path context is a fan-out attack surface — one compromise affects every embedding dApp simultaneously, and the realised-loss-bound is the union of the embedding dApps' end-user value-at-risk during the compromise window.
The structural parallel within the OAK corpus is the Curve DNS hijack case at /examples/2022-08-curve-dns-hijack.md. Both cases illustrate that the dApp signing-path surface is wider than the dApp's own code and includes the full chain of distribution dependencies — npm packages (Ledger Connect Kit), DNS resolution (Curve), CDN edges, front-end hosting. The set of distribution-layer surfaces that can produce a signing-path compromise affecting many users is wider than the contract-layer surface that dominates the OAK-T9 family; OAK's worked-example layer should make the breadth of the distribution-layer signing-path surface explicit, not only across npm and DNS but also across the broader ecosystem (Cloudflare workers, Vercel / Netlify hosting, browser-extension publish paths).
The credential-rotation-discipline-on-package-publish-credentials dimension is the Ledger-specific analytical contribution. The structural lesson is that package-publish credentials operate in CI / build-system contexts that may not be visible to standard offboarding workflows; the credential-rotation gap that produced the December 2023 entry vector was not exotic — it is the kind of gap that exists at many organisations publishing critical npm packages, particularly those with developer-team turnover. Defender practice for any organisation publishing critical npm packages should include explicit package-publish credential inventory and rotation discipline as part of offboarding workflows, with the Ledger case as the canonical worked example of what happens when this discipline is not in place.
The publish-path-MFA-enforcement dimension is the second Ledger-specific analytical contribution. The npm registry's industry-wide push toward enforced MFA on critical packages accelerated through 2024 in part as a downstream effect of the Ledger Connect Kit case and the broader late-2023 / 2024 npm-supply-chain-compromise cohort; this is the kind of cohort-level mitigation deployment that the OAK Mitigations layer should track explicitly, with the Ledger case as the proximate-causal example of what motivated the registry-level policy change.
For OAK's broader credibility, including Ledger Connect Kit in v0.1 closes three gaps: it adds the canonical 2023 worked example of the npm-supply-chain-compromise sub-class to a corpus that otherwise treats supply-chain compromise as a 2024–2025 phenomenon (DMM, Bybit), it documents the npm-package-as-signing-path dimension as a structural framing point that the Mitigations layer should cover explicitly, and it provides the structural parallel-and-contrast with the Curve DNS hijack case that anchors the distribution-layer signing-path surface is wider than the dApp's own code lesson as a discrete defensive-design surface.