Ledger Hack: How the Connect Kit Exploit Worked
Ledger Hack Investigation: Attack Vector, Affected dApps and Drainers
Ledger owners should read news of an intrusion into the maker’s infrastructure as a trigger to audit their own setup, not as a reason to move funds: confirm that firmware was installed through the official companion app, confirm that the 24-word recovery phrase has never been typed into a phone, browser, spreadsheet, or chat window, and confirm that every outgoing transfer is approved on the device display after the destination address has been checked character by character.
The architecture explains why the chip itself survives most attacks. Private keys are generated inside a certified secure element during first setup and stay there for the life of the unit; the companion software holds only public account data, and a signature appears only after the PIN is entered and the amount and recipient are visible on the built-in screen. A leaked database, a misused support ticket, or a stolen shipping list therefore cannot pull the phrase out of the hardware – those words never exist in readable form outside the device.
Real losses land on the human layer around the chip. Impersonators who call, message, or open a chat window and request the 24 words are chasing the single string that drains an account, and no employee, developer, or support agent will ever ask for it. The same ban applies to web forms, browser extensions, cloud notes, and photographs of the recovery sheet. A lookalike download page serving a tampered build of the companion app is the other standard lure, so type the official address by hand instead of clicking an advertisement or a link sent by a stranger.
Buy the unit only from the manufacturer or an authorized reseller, and initialize it yourself. A device that arrives with a filled-in recovery card has been set up by someone else and must go back; a genuine first boot generates a fresh phrase on its own screen. Copy those words onto paper or metal, keep two copies in separate physical places, and never save them as a photo, a text file, or an entry in a password manager tied to an online account.
For balances that justify the extra effort, attach a passphrase to a second PIN, which creates a separate set of accounts so the 24 words alone no longer open the main holdings. Rehearse the restore path with a small amount before trusting the device with a large one – an untested backup fails precisely when it is needed. Self-custody has one hard limit worth accepting up front: an exchange can reset a password, while nobody can reset a missing phrase.
The device display stays the final checkpoint against a poisoned smart contract or a swapped recipient, so sign nothing that has not been read on that screen. Update firmware and currency apps through the official companion software only, and treat any request for the recovery words – by call, mail, chat, or pop-up – as fraud, regardless of how the sender identifies themselves.
What Attack Vector Led to the Ledger Connect Kit Compromise?
Pin every browser-side dependency to a cryptographic hash and treat any freshly published build as untrusted until its digest matches what you reviewed: the intrusion arrived as a poisoned release of a widely imported JavaScript module, pushed through a stolen publisher credential, not through any weakness in the signing hardware itself.
How a Poisoned Build Reached Live Pages
That module handled the handshake between a decentralised application’s page and the physical signer. Whoever controlled the hijacked publishing token swapped a benign loader for a compact script that pulled a drainer from an attacker-held domain, then rewrote the recipient field inside the outgoing request. No firmware was modified, no recovery phrase was ever requested, and the substitution occurred entirely in the browser before the payload reached the screen.
This is why reading the destination address on the device display remains the strongest single defence. A user who compared what the screen showed against the address they intended to pay caught the mismatch instantly; a user who approved without looking did not. Because the malicious loader lived inside the application’s own origin, it inherited every privilege that page already held, including the ability to mutate the request object long before the signer ever parsed it – and because it depended on a remote host staying reachable, the exposure was bounded to the window in which both the poisoned release and that host remained live. Isolated key storage keeps secrets off the internet, but it cannot vouch for the contents of a transaction, which is exactly the gap the on-screen check closes.
Audit which accounts may publish under your dependency namespaces, enforce two-factor authentication and short-lived scoped tokens on the registry, and turn on subresource integrity wherever a front end loads remotely hosted code.
If you interacted with an affected page, revoke token allowances for every asset, transfer whatever remains to an account generated fresh on the device, and re-verify the written backup of that new account before funding it. Clean-up therefore splits into two halves: on-chain approval removal for the old addresses, and on-device account creation to leave the contaminated approval history behind.
How to Identify If Your Wallet Interacted with the Malicious Script?
Check the protected chip screen for every transaction prompt; it displays the destination address and amount without relying on the companion application, so a script that alters the app’s display cannot change what you see on the device.
Open the companion application and review the operation history for any signature request you did not initiate. Compare each entry against the physical confirmation you performed on the device; the app cannot sign without that button press, so an unapproved entry indicates a script attempted to queue an operation but failed. Also inspect the connection log for repeated or unexpected pairing attempts from unknown sources.
Inspect the protected chip screen during any connection to the companion app: a legitimate transaction shows the full destination address on the chip display, while a script-driven request may show a truncated or mismatched address. Look for any prompt that appears without your action, such as a transaction summary or firmware update request; the device requires physical confirmation for firmware changes, and an unexpected prompt means the script tried to interact. Cross-check any address displayed on the device against the one shown in the app; a discrepancy reveals script interference. Use a second, offline device to verify addresses if you suspect tampering. The table below lists concrete checks.
| Check | Where to verify | Indicator of script interaction |
|---|---|---|
| Transaction destination address | Protected chip screen | Address differs from the one shown in the companion app or appears without your initiation |
| Operation history | Companion app | Pending signature request you did not approve on the device |
| Firmware update prompt | Protected chip screen | Update request appears without your action or shows a provider name not matching official sources |
| Pairing request | Companion app connection log | Repeated or unknown device pairing attempts |
Which Wallets and dApps Were Affected by the Ledger Connect Kit Exploit?
Treat every decentralized front end that loaded the Connect Kit bundle as compromised until its maintainers say otherwise: the malicious code was injected into a shared connector library, so it surfaced on any page that pulled that build, no matter which device the visitor used.
Projects That Pulled the Poisoned Connector Build
The altered dependency reached people through the front-end layer, so the affected group was defined by build pipelines rather than by brands: swap interfaces, lending dashboards, non-fungible token marketplaces, bridges, yield aggregators and portfolio trackers that imported the package or served it from a server. Any site loading that script while the tampered build sat in the registry could have shown a decoy prompt asking the visitor to sign a transfer or an approval. Teams that bundled the library into their own files, self-hosted it behind a content delivery network or pinned an earlier release were untouched. Because the bad file was withdrawn and replaced, the practical test is not “was my favourite app named” but “did the request I signed show a destination I recognised”.
What Remained Outside the Affected Set
The hardware signer, the firmware on its secure element, the recovery phrase generated inside that chip and the companion dashboard used to view balances and prepare transfers were never part of the injection. Keys never left the device and no remote script could read them. What the hostile build could do was propose a transfer for the owner to approve, which throws the whole outcome back onto the physical screen: address, amount and network shown there are the final checkpoint. Anyone who rejected an unfamiliar prompt, or who signed nothing, lost nothing.
If you approved an unexpected request on that screen, move the holdings to a newly generated account right away.
Rebuilding confidence takes verifiable steps rather than reassurance. Freeze the connector dependency at a known-good release, commit the lockfile and keep its integrity hash so a silent swap breaks the install. Serve third-party scripts from your own origin with integrity attributes, restrict them with a content policy header, and watch the registry for re-publishes. On the user side, download only from the manufacturer’s own domain, treat any prompt requesting the full recovery phrase as fraudulent, and check the address in character groups on the device display. The vendor’s advisory pages and support documentation carry the current list of affected integrations and patched builds; that list is the part that changes, so read it there instead of from a screenshot.
What On-Chain Signs Distinguish a Drainer Transaction from Normal Approval?
Reject any approval whose decoded spender is an unverified contract, whose amount is unlimited, or whose method is setApprovalForAll unless you deliberately created that permission.
Decode the transaction input before signing. A normal ERC-20 approval has To equal to the token contract, selector 0x095ea7b3, and two fields: spender and amount. Check the spender against the contract you intended to use; an exact amount and a known router or bridge contract fit a routine approval, while a fresh spender contract with no source code or no prior activity does not.
Treat selector 0xa22cb465, setApprovalForAll, as a broad grant over every token in a collection; use it only for a marketplace or contract you can identify on the signer screen. Selector 0x39509351, increaseAllowance, and approve with amount 2^256-1 create effectively unlimited permission. An approval to an externally owned address is rare in normal flows; reject it unless that address is yours and you understand why it needs an allowance. Check the spender’s first transaction and contract verification in the explorer, then compare the decoded spender with the address shown in the companion app’s simulation.
Watch the post-approval sequence. A drainer often produces an Approval event, then a transferFrom call from the spender contract in the same or next block, moving the full balance to an address unrelated to the original service. A normal router pulls only the exact approved amount during a swap and sends output back to your account.
Permit and Permit2 flows leave no approval transaction at first: you sign typed data off-chain, then a relayer submits permit and transferFrom on-chain. On-chain, look for a Permit event with owner set to your address and spender set to an unfamiliar contract, followed by a Transfer from your address; a normal approval instead emits Approval directly from the token contract. On the hardware signer screen, read the domain, spender, amount and deadline; reject unlimited amounts, unknown spenders and blind signing, because the device is the last place where the decoded permission can be stopped.
Confirm the signer screen shows the token contract, spender, amount and method; reject any mismatch with the companion app simulation, any unlimited amount, and any setApprovalForAll request you did not intend.
How to Revoke Token Approvals and Disconnect Compromised Sessions?
Revoke outstanding allowances first, delete active pairings second, and only then decide whether the accounts themselves have to be replaced.
An allowance is a signed permission stored on-chain: it lets a specific contract move up to a set amount of one token from your address without asking you again, and it does not expire on its own. Ledger Live shows balances per account, but the list of spenders lives in the public ledger, so you read it through a blockchain explorer’s approval viewer using the account’s public address – never by typing your recovery phrase into any site.
Revocation means sending a transaction that resets each allowance to zero, and each one costs a network fee, so work through the list in order of exposure: unlimited amounts first, then unknown contracts, then anything you no longer recognise. Connect the Ledger device, keep Ledger Live open next to the browser tool, and pick the account whose approvals you are clearing. Because some contracts are not decoded by the app, you may need to switch on blind signing for that single signing session; the device screen then shows raw data instead of a readable description, so check the network, the spender address and the fee against what the browser tool claims before pressing the physical button. Confirm, wait for the transaction to settle, re-scan the address, and repeat until nothing remains. Turn blind signing off again once the cleanup is finished.
Revocation closes a door; it never returns what already walked through it.
Sessions are separate from allowances. Inside Ledger Live, open the pairing area and review every listed connection – origin, chain, permissions – then delete each entry you cannot justify. The dApp may hold its own session token on its servers, so log out there as well. The signing device itself keeps no session state: keys stay inside the secure element and every request still requires a physical confirmation on the screen, which is the barrier an attacker hits when the pairing is deleted.
If the 24 words were ever entered into a website, a chat window or an app screen built to imitate Ledger Live, treat every account derived from that phrase as lost. Resetting approvals does not help, because whoever holds the words can regenerate the same keys and sign transfers at will. Reset the device to factory settings, generate a fresh recovery phrase, write it down offline, and move the remaining balance to the new addresses. Drainers often wait weeks before sweeping, so leave the old addresses empty.
Habits that reduce repeat exposure: keep a small, separate account for experiments with new contracts, approve finite amounts rather than unlimited ones, review spenders on a schedule, and treat any message asking for your recovery phrase as fraud – genuine support never requests it.
Q&A:
Does the Ledger hack mean my Ledger hardware wallet is compromised?
The incident involved Ledger Connect Kit, a JavaScript library used by some Web3 apps. It did not break the hardware wallet’s secure element or reveal your recovery phrase. If you only used your Ledger to sign transactions and did not connect to affected dApps during the attack window, your device and keys likely remain safe. Still, any transaction you signed while the malicious code was active could have sent funds to an attacker. Check official Ledger updates and blockchain records. If you approved a suspicious transaction, move remaining assets to a fresh wallet with a new seed phrase.
What exactly was hacked, and who was behind it?
The hack targeted Ledger’s Connect Kit, a software package that helps websites connect to wallets. Attackers changed the package so it loaded a wallet-draining script. The issue was in the supply chain, not the Ledger hardware device itself. Ledger worked with partners to remove the malicious version. The attacker’s identity may still be under investigation. This shows how a single compromised dependency can affect many crypto users.
How can I tell if I was affected by the Ledger hack?
Review your wallet activity around the time the malicious Connect Kit version was active. Look for transactions you did not initiate, approvals to unknown contracts, or token transfers you do not recognize. If you interacted with a dApp that used Ledger Connect Kit during that window, you may have been exposed. Check your address on a block explorer and compare with your own records. Ledger and security researchers published lists of affected dApps and the time frame. If you see unauthorized movements, treat the wallet as unsafe and create a new one.
Should I stop using Ledger devices after this?
The hardware wallet’s core design still protects private keys from being extracted remotely. The hack did not change that. However, the incident shows that the software around your wallet can be a weak point. You can keep using a Ledger if you follow good habits: verify every transaction on the device screen, avoid blind signing, use official apps, and keep firmware updated. If you feel uneasy, moving to another hardware wallet is a personal choice. No wallet is risk-free, but separating long-term storage from daily hot-wallet activity reduces exposure.
What broader lessons does this hack teach about crypto wallet security?
The main lesson is that wallet security includes devices, apps, browser extensions, smart contracts, and the software supply chain. A hardware wallet can keep keys offline, but if a web page asks you to sign a harmful transaction, the device may still approve it if you do not check details. Users should treat every signature request as a potential risk. Developers should pin dependencies, audit updates, and use multi-signature setups for large holdings. Exchanges and dApps should monitor for unusual library changes. The event also highlights why public disclosure and fast patching matter.
