From 64fc5eb0c723cf668b5b2ce318fabb2c2a3f0091 Mon Sep 17 00:00:00 2001 From: Nicolas Iooss Date: Fri, 15 Sep 2023 16:45:30 +0200 Subject: [PATCH 1/2] LSB 020 --- _lsb/020.md | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lsb.md | 1 + 2 files changed, 68 insertions(+) create mode 100644 _lsb/020.md diff --git a/_lsb/020.md b/_lsb/020.md new file mode 100644 index 0000000..6a195f4 --- /dev/null +++ b/_lsb/020.md @@ -0,0 +1,67 @@ +--- +layout: page +title: Ledger Security Bulletin 020 +summary: Ledger Live incorrectly parses some EIP-712 messages +--- + +15 September 2023: Ledger Live incorrectly parses some EIP-712 messages + +## Summary + +When requesting to sign typed EIP-712 messages through Ledger Live and a Ledger device, the message which was actually signed could be different from the intended one. + +More precisely, if an integer field contained a hexadecimal number with an odd number of characters, its value was reduced. +For example, requesting the signature of a message meaning "I want to sell this asset for 0x123 tokens", the signature of "I want to sell this asset for 0x12 tokens" would have been produced. + +This issue is fixed in [`ledgerhq/hw-app-eth`](https://www.npmjs.com/package/@ledgerhq/hw-app-eth) version 6.34.7, included in [Ledger Live](https://www.ledger.com/ledger-live) 2.70.0. + +## Description + +[EIP-712](https://eips.ethereum.org/EIPS/eip-712) is a standard which defines a way to sign messages with several fields. +This can be used to authorize some actions without sending a transaction on Ethereum. +For example, let's imagine a marketplace where users can sell their assets and the Ethereum transaction fees are paid by the buyer. +A way to do implement this mechanism would consist in signing a message containing some identifier of the asset, the address of the buyer and the value: + +1. The seller crafts a EIP-712 message with all the needed information and signs it. +2. The seller shares this message with the buyer. +3. The buyer invokes a method of the smart contract of the marketplace to claim the asset. This invocation is an Ethereum transaction which also transfers enough tokens to the seller. + +(N.B. This is a simple example. A real marketplace protocol is likely to include more fields to be secure, like a way for the seller to cancel the trade if the buyer takes too long to make the transaction.) + +In practice, the first step can be implemented by using [WalletConnect](https://walletconnect.com/)'s package [`walletconnect/sign-client`](https://www.npmjs.com/package/@walletconnect/sign-client) and invoking the method `eth_signTypedData_v4`. +The signed message can have a field named `value` using type `uint256`. + +If the seller uses Ledger Live with a Ledger Nano X device, the message to be signed goes through several libraries before hitting the device. +A problem occurs when the integer in field `value` is encoded in hexadecimal: one of these libraries (`ledgerhq/hw-app-eth`) decodes it incorrectly and propagates this wrong value. +For example `0x123` (which is the number 291) is decoded to `0x12`, which is 18. +This leads to the Nano X displaying a hash which does not match the initial message. +If the user approves this hash, the signed message is incorrect and an attacker who manages to get this signature can abuse it to buy the asset for 18 tokens instead of 291. + +Thankfully, Ledger Live also displays the right hash of the message, so users can find out that something wrong is going on. +If you encounter a situation where the data displayed by Ledger Live does not match the one on your device, please reject the signature and contact [Ledger's support](https://support.ledger.com/hc/en-us/articles/4423020306705-Contact-Us?support=true) instead, as this could be a bug in our products. + +## Root cause of the issue + +The issue was caused by using Node.js's function [`Buffer.from`](https://nodejs.org/docs/latest-v18.x/api/buffer.html#static-method-bufferfromstring-encoding) to decode a hexadecimal number in bytes. +When this function encounters an odd number of characters, it ignores the last one. +This can be reproduced in Node.js' interactive command-line interface: + +```console +$ node +> Buffer.from("1234", "hex") + + +> Buffer.from("123", "hex") + +``` + +To fix this, [`hw-app-eth/src/utils.ts`](https://github.com/LedgerHQ/ledger-live/blob/%40ledgerhq/hw-app-eth%406.34.5/libs/ledgerjs/packages/hw-app-eth/src/utils.ts#L21-L23) was modified to automatically prepend a `0` to the string before decoding it, in [Ledger Live's Pull Request #4687](https://github.com/LedgerHQ/ledger-live/pull/4687). + +## Mitigations + +Version 6.34.7 of [`ledgerhq/hw-app-eth`](https://www.npmjs.com/package/@ledgerhq/hw-app-eth) fixed the issue. +It is recommended for all projects using it to update to the newest version. + +## Credits + +We would like to thank Ian Fisher, who discovered the vulnerability and disclosed it through our bug bounty program. diff --git a/lsb.md b/lsb.md index 971a9df..c141bb9 100644 --- a/lsb.md +++ b/lsb.md @@ -13,6 +13,7 @@ through the [bug bounty program](/bounty/). | Date | Title | |------------|-----------------------------------------------------------------| +| 2023-TODO | [LSB 020: Ledger Live incorrectly parses some EIP-712 messages](020) | | 2023-05-11 | [LSB 019: Invalid addresses for certain miniscript policies](019) | | 2022-08-05 | [LSB 018: Invalid command processing on HSM firmware](018) | | 2022-07-04 | [LSB 017: Keycard bypass on Ledger HW.1](017) | From 8e74d3e0886f4ddfb6bb2e4ebbce8151d8feb3ba Mon Sep 17 00:00:00 2001 From: mmouchous-ledger Date: Mon, 20 Nov 2023 08:39:16 +0100 Subject: [PATCH 2/2] Update dates to publication day --- _lsb/020.md | 2 +- lsb.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_lsb/020.md b/_lsb/020.md index 6a195f4..aaf92c9 100644 --- a/_lsb/020.md +++ b/_lsb/020.md @@ -4,7 +4,7 @@ title: Ledger Security Bulletin 020 summary: Ledger Live incorrectly parses some EIP-712 messages --- -15 September 2023: Ledger Live incorrectly parses some EIP-712 messages +20 November 2023: Ledger Live incorrectly parses some EIP-712 messages ## Summary diff --git a/lsb.md b/lsb.md index c141bb9..47935d5 100644 --- a/lsb.md +++ b/lsb.md @@ -13,7 +13,7 @@ through the [bug bounty program](/bounty/). | Date | Title | |------------|-----------------------------------------------------------------| -| 2023-TODO | [LSB 020: Ledger Live incorrectly parses some EIP-712 messages](020) | +| 2023-11-20 | [LSB 020: Ledger Live incorrectly parses some EIP-712 messages](020) | | 2023-05-11 | [LSB 019: Invalid addresses for certain miniscript policies](019) | | 2022-08-05 | [LSB 018: Invalid command processing on HSM firmware](018) | | 2022-07-04 | [LSB 017: Keycard bypass on Ledger HW.1](017) |