Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move Ethereum Ledger integration in untrusted iframe #14373

Merged
merged 1 commit into from
Aug 18, 2022

Conversation

nvonpentz
Copy link
Member

@nvonpentz nvonpentz commented Jul 27, 2022

Resolves brave/brave-browser#24275

Security Review: https://github.com/brave/security/issues/969

This changes isolates the js libraries required to interact with the Ethereum app on Ledger devices to an iFrame in a chrome untrusted context. This uses the same framework used in the Solana hardware as #14096, but generalizes some code such that it can be reused for both Solana and Ethereum. For example:

  • Shared logic in SolanaLedgerBridgeKeyring class was moved to a new parent class that LedgerBridgeKeyring that both SolanaLedgerBridgeKeyring and EthereumLedgerBridgeKeyring inherit from
  • Solana specific logic was moved from LedgerUntrustedMessagingTransport to a new child class SolanaLedgerUntrustedMessagingTransport. Similarly, Ethereum specific logic is now in a child class EthereumLedgerUntrustedMessagingTransport.
  • Common message types were kept in ledger-messages.ts, but Solana and Ethereum specific message types were separated into their own sol-ledger-messages.ts and eth-ledger-messages.ts module.

Submitter Checklist:

  • I confirm that no security/privacy review is needed, or that I have requested one
  • There is a ticket for my issue
  • Used Github auto-closing keywords in the PR description above
  • Wrote a good PR/commit description
  • Squashed any review feedback or "fixup" commits before merge, so that history is a record of what happened in the repo, not your PR
  • Added appropriate labels (QA/Yes or QA/No; release-notes/include or release-notes/exclude; OS/...) to the associated issue
  • Checked the PR locally: npm run test -- brave_browser_tests, npm run test -- brave_unit_tests, npm run lint, npm run gn_check, npm run tslint
  • Ran git rebase master (if needed)

Reviewer Checklist:

  • A security review is not needed, or a link to one is included in the PR description
  • New files have MPL-2.0 license header
  • Adequate test coverage exists to prevent regressions
  • Major classes, functions and non-trivial code blocks are well-commented
  • Changes in component dependencies are properly reflected in gn
  • Code follows the style guide
  • Test plan is specified in PR before merging

After-merge Checklist:

Test Plan:

The test plan is very similar to the test plan for the parallel Solana untrusted refactor, except instead of testing Solana Ledger functions, we test the Ethereum ones.

  1. Test import accounts flow (chrome://wallet)
    1. Connect ledger device and enter password
    2. Run (await navigator.hid.getDevices()).forEach((d) => d.forget()) in the js console to forget devices which have already been granted permissions, then refresh the page
    3. Click 'Import from hardware wallet' -> 'Connect' for Ethereum, Select 'Ledger', click 'Connect'
    4. Verify 'Grant Brave access to your Ledger device.' is displayed, hit 'Authorize'
    5. You should be prompted with the permissions screen, select device, hit 'Connect'
    6. Verify you are returned to 'Connect your Ledger wallet directly to your computer' screen, hit 'Connect'
    7. Verify your accounts are listed for import for import. Verify you can load 'Load more' accounts
    8. Verify you can load different accounts by switching derivation paths
    9. Select an account and hit 'Add checked accounts', verify it is added
    10. Repeat the same flow without forgetting the device first and verify no 'Authorize' screen is displayed or permission screen prompted.
  2. Test signing flows (chrome://wallet-panel) for (a) sign transaction, (b) sign personal, (c) sign typed data
    1. Connect ledger device and enter password
    2. Create a Ethereum hardware account with a test net balance if you don't have one already
    3. Navigate to chrome://inspect > Other
    4. Open wallet panel, and click 'inspect' on the chrome://inspect page under the 'chrome://wallet-panel.top-chrome' item that pops up. This is the js console for the panel
    5. Run (await navigator.hid.getDevices()).forEach((d) => d.forget()) to forget any device which already has permissions on the panel (need to be quick since this closes not long after the panel closes)
    6. Do one of
      1. Create a standard transaction in the panel sending funds to yourself (sign transaction)
      2. Go to OpenSea and like any NFT (I'm partial to lil nouns) by clicking the heart (sign personal)
      3. Go to https://metamask.github.io/test-dapp/, connect wallet, and sign + verify 'Sign Typed Data V3' and 'Sign Typed Data V4'
    7. Hit sign / confirm
    8. You should be shown an 'Authorize' button on the panel that says the device is disconnect, click the 'Authorize' button
    9. You should be prompted with the permissions screen, select device, hit 'Connect'
    10. Verify you are returned to the 'Hardware wallet requires Ethereum App opened on Ledger' (it may take a second)
    11. On your ledger device, you should see the the transacition / sign request you entered, confirm.
    12. Verify the post transaction / signing stuff happens: you are shown the details, get a notification when transaction is confirmed, the 'like' is registered by OpenSea, etc
    13. Repeat all steps until all of sign transaction, sign personal, and sign typed data have been completed successfully

@github-actions github-actions bot added the CI/storybook-url Deploy storybook and provide a unique URL for each build label Jul 27, 2022
@nvonpentz nvonpentz force-pushed the ethereum-ledger-untrusted branch 2 times, most recently from ce4e043 to a04e699 Compare August 2, 2022 20:44
@nvonpentz nvonpentz changed the title WIP: Ethereum ledger untrusted Isolate Ethereum Ledger integration in untrusted iFrame Aug 2, 2022
@nvonpentz nvonpentz marked this pull request as ready for review August 2, 2022 20:45
@nvonpentz nvonpentz changed the title Isolate Ethereum Ledger integration in untrusted iFrame Move Ethereum Ledger integration in untrusted iframe Aug 4, 2022
components/brave_wallet_ui/common/api/hardware_keyrings.ts Outdated Show resolved Hide resolved
components/brave_wallet_ui/common/async/hardware.ts Outdated Show resolved Hide resolved
'm/44\'/60\'/0\'/0/0', 'domainSeparatorHex', 'hashStructMessageHex'))
.resolves.toStrictEqual({ success: false, error: 'some error', code: 'Error' })
})
// class MockApp {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we removing this file before merge?

@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

Copy link
Member

@kdenhartog kdenhartog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

few nits spotted, but overall this looks good to me

@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

Copy link
Contributor

@josheleonard josheleonard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Frontend ++

@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

This change isolates the ledgerjs libraries required to interact with the
Ethereum app on Ledger devices to an iFrame in a chrome untrusted context.
It reuses the framework established in the Ledger Solana Ethereum refactor,
but generalizes some code such that it can be reused for both Solana and
Ethereum. For example:

* Shared logic in SolanaLedgerBridgeKeyring class has been moved to a new
  parent class that LedgerBridgeKeyring that both SolanaLedgerBridgeKeyring
  and EthereumLedgerBridgeKeyring that both inherit from

* Solana specific logic was moved out of LedgerUntrustedMessagingTransport
  and into a new child class, SolanaLedgerUntrustedMessagingTransport.
  Similarly, Ethereum specific logic is now in a new child class,
  EthereumLedgerUntrustedMessagingTransport that inherits from
  LedgerUntrustedMessagingTransport.

* Common message types were kept in ledger-messages.ts, but Solana and
  Ethereum specific message types were separated into their own
  sol-ledger-messages.ts and eth-ledger-messages.ts modules
  respectively.
@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

@nvonpentz nvonpentz merged commit d098592 into master Aug 18, 2022
@nvonpentz nvonpentz deleted the ethereum-ledger-untrusted branch August 18, 2022 20:47
@github-actions github-actions bot added this to the 1.44.x - Nightly milestone Aug 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI/storybook-url Deploy storybook and provide a unique URL for each build
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Move Ethereum Ledger Integration to untrusted iframe
6 participants