Repository navigation
Conversation
Wires the signature address scanning feature into the confirmation flow using `extractSignatureAddresses` from `@metamask/phishing-controller` rather than a local copy of the extractor. After PPOM validates a v3/v4 typed-data signature request and returns a non-malicious result, address-typed fields in the EIP-712 message are extracted and scanned via `PhishingController.scanAddress`. Results are surfaced as alerts via the new `useSignatureAddressAlerts` hook. Note: requires a bump to the `@metamask/phishing-controller` version that exports `extractSignatureAddresses` (pending MetaMask/core PR). Related: MetaMask#34428
Contributor
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
Contributor
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Reviewed by Cursor Bugbot for commit e9ad9bd. Configure here.
matthewwalsh0
self-requested a review
August 14, 2026 11:01
matthewwalsh0
previously approved these changes
Aug 17, 2026
| /** | ||
| * Generate trust-signal alerts for the address fields of a typed-data signature. | ||
| */ | ||
| export function useSignatureAddressAlerts(): Alert[] { |
Member
There was a problem hiding this comment.
Can we use something more explicit like useSignatureTrustSignalAlerts?
Author
There was a problem hiding this comment.
Great point! I applied this change
Member
There was a problem hiding this comment.
Minor, hook was renamed but not file itself.
… and extract baseAlert
matthewwalsh0
approved these changes
Aug 23, 2026
3 of 4 tasks
pull Bot
pushed a commit
to Reality2byte/core
that referenced
this pull request
Sep 10, 2026
…12 typed-data scanning (MetaMask#10170) ## Explanation Ticket: [PSAFE-441](https://consensyssoftware.atlassian.net/browse/PSAFE-441) Supersedes [MetaMask#9875](MetaMask#9875) (same change, opened from a core branch so changelog CI can resolve the head). Review comments on that PR were addressed there. MetaMask validates `eth_signTypedData_v3` and `eth_signTypedData_v4` requests with PPOM, which inspects the address fields of a signature. PPOM's threat data is refreshed on a delay, so an address that has been flagged recently can still be reported as benign, and it does not cover every chain or protocol. Separately, the real-time per-address scan (`/address/evm/scan`) is only applied to a few fields today: the token `verifyingContract`, permit `spender`, and delegation `delegate`. Addresses carried in any other field — recipients, makers, tokens, custom protocol fields — receive no real-time scan at all. This change adds a schema-driven extractor that returns up to 10 distinct `address`-typed values found in a typed-data message (including nested structs and arrays, matched by declared type rather than field name), and reports when the message could not be fully walked because the address cap, depth limit, or work budget was reached. When PPOM has not already flagged the request, the extracted addresses are passed to the real-time address scan. Results reuse the existing address cache, so fields already scanned elsewhere are not requested again. ### What this exports - `extractSignatureAddresses(typedData, options)` — walks `types`/`primaryType`/`message`, returns `{ addresses, fields, overflow, maxAddresses }` - `ExtractedSignatureAddresses` — return type - `ExtractSignatureAddressesOptions` — options: `exclude` (addresses to skip, e.g. the signer), `excludeFields` (top-level field names to skip, e.g. `spender` when already covered by an existing scan), `maxAddresses` (optional cap override; default 10, hard ceiling 50) - `DEFAULT_MAX_SIGNATURE_ADDRESSES` and `MAX_SIGNATURE_ADDRESSES_CEILING` — exported so clients can word overflow copy and stay aligned with the default/ceiling ### Safeguards - Cap of 10 distinct addresses per message by default, overridable via `maxAddresses` up to 50 - Max traversal depth of 12 - Max 5000 nodes visited - `overflow: true` is returned whenever the walk is incomplete so callers can surface a caution ## References - Prior fork PR (same change): MetaMask#9875 - MetaMask Extension (client wiring): MetaMask/metamask-extension#45521 - MetaMask Mobile (client wiring): MetaMask/metamask-mobile#34786 - Prior implementation with local extractor copy (Extension): MetaMask/metamask-extension#45058 - Prior implementation with local extractor copy (Mobile): MetaMask/metamask-mobile#34428 ## Changelog See `packages/phishing-controller/CHANGELOG.md`. ## Checklist - [x] Tests written and passing - [x] Changelog updated - [x] Exports added to `index.ts` - [ ] Version bump (pending release cut) [PSAFE-441]: https://consensyssoftware.atlassian.net/browse/PSAFE-441?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Security-adjacent signing flow support: incorrect normalization or missed addresses could weaken typed-data scanning when clients adopt the export, though behavior is heavily tested and bounded with overflow signaling. > > **Overview** > Adds **`extractSignatureAddresses`**, a schema-driven helper that walks EIP-712 `types`/`primaryType`/`message` and collects distinct **`address`-typed** values (including nested structs and arrays) for downstream real-time address scanning—not hard-coded field names like `spender` or `to`. > > The function **normalizes** values the same way signing does (hex/decimal, leading 20 bytes, lowercase dedupe), supports **`exclude`**, top-level **`excludeFields`**, and a configurable distinct-address cap (**default 10**, ceiling **50**). It returns **`addresses`**, per-address **`fields`** for alert copy, and **`overflow`** when traversal hits caps, depth (12), or a 5000-node budget so clients can warn when not every address was collected. **`DEFAULT_MAX_SIGNATURE_ADDRESSES`** and **`MAX_SIGNATURE_ADDRESSES_CEILING`** are exported from **`index.ts`** alongside the new types. > > Ships **`signature-address-extraction.ts`**, a large Jest suite (including **`@metamask/eth-sig-util`** parity checks), changelog entry, and **`eth-sig-util`** as a **devDependency** only—no **`PhishingController`** wiring in this PR. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 732e1c3. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Alex Donesky <adonesky@gmail.com>
8 of 10 tasks
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Ticket: PSAFE-441
MetaMask validates
eth_signTypedData_v3andeth_signTypedData_v4requests with PPOM, which inspects the address fields of a signature. PPOM's threat data is refreshed on a delay, so an address that has been flagged recently can still be reported as benign, and it does not cover every chain or protocol.Separately, the real-time per-address scan (
/address/evm/scan) is only applied to a few fields today: the tokenverifyingContract, permitspender, and delegationdelegate. Addresses carried in any other field — recipients, makers, tokens, custom protocol fields — receive no real-time scan at all.This change wires a schema-driven extractor (added to
@metamask/phishing-controllerin MetaMask/core#9875) that returns up to 10 distinctaddress-typed values found in a typed-data message, including nested structs and arrays, matched by declared type rather than field name. When PPOM has not already flagged the request, those addresses are passed toPhishingController.scanAddress. Results reuse the existing address cache, so fields already scanned elsewhere are not requested again. A confirmation alert surfaces any flagged address using the existing alert template, naming the flagged field and address. If some addresses could not be checked because the cap, depth limit, or work budget was reached, a separate caution is shown.Changes
app/lib/address-scanning/scan-unvalidated-signature.ts(new) — extracts up to 10 address-typed fields and scans each viaPhishingController.scanAddressafter PPOM; excludes signer and zero addressapp/components/Views/confirmations/hooks/alerts/useSignatureAddressAlerts.ts(new) — hook that reads scan results and returns alerts for malicious/warning addresses (naming the field) plus a caution when the walk was incompleteapp/lib/ppom/ppom-util.ts— callsscanUnvalidatedSignatureAddressesafter PPOM for v3/v4 requests when PPOM has not flagged the requestapp/components/Views/confirmations/constants/alerts.ts— addsSignatureAddressScanIncomplete,SignatureAddressTrustSignalMalicious,SignatureAddressTrustSignalWarningtoAlertKeysapp/components/Views/confirmations/hooks/alerts/useConfirmationAlerts.ts— wiresuseSignatureAddressAlertsintouseSignatureAlerts()app/components/Views/confirmations/hooks/metrics/useConfirmationAlertMetrics.ts— adds metric entries for the three new alert keyslocales/languages/en.json— addsalert_system.signature_address_scan.*stringsDependencies
Blocked on MetaMask/core#9875. The
package.jsondependency on@metamask/phishing-controllermust be bumped to the version that exportsextractSignatureAddressesbefore this can merge.References
Test plan
fromfield — confirm a Danger alert appears naming the field and shortened addressspenderalertScreenshots/Recordings
Both recordings sign the same typed-data request — the message carries a flagged address in a non-permit field.
Before
Baseline build. The flagged address raises no alert on the confirmation screen.
simulator.screen.before.mov
After
With this change, the same request shows a danger alert on the "Interacting with" row naming the field and address.
Simulator.screen.after.mov
Note
Medium Risk
Touches signature confirmation security alerts and PPOM post-validation scanning. Behavior is additive and gated, but incorrect extraction or alert mapping could hide or over-flag threats.
Overview
Adds real-time phishing scans for address-typed fields in
eth_signTypedData_v3/v4messages, covering nested structs and custom fields that PPOM or permit-only scans miss.After PPOM, if the result is not already malicious or warning,
scanUnvalidatedSignatureAddressesextracts addresses (excluding the signer) viaextractSignatureAddressesand scans them throughPhishingController. Confirmation UI then shows danger/warning alerts naming the field and address, plus a caution when the extractor hits its cap.Gated on security alerts / Blockaid being enabled. Personal sign and typed-data v1 are skipped. Metrics keys are added for the three new alerts.
Reviewed by Cursor Bugbot for commit 098fd99. Bugbot is set up for automated code reviews on this repo. Configure here.