Skip to content

feat(transaction-controller): gate internal validations on explicit isInternal flag#8633

Draft
matthewwalsh0 wants to merge 2 commits intomainfrom
feat/transaction-controller-is-internal
Draft

feat(transaction-controller): gate internal validations on explicit isInternal flag#8633
matthewwalsh0 wants to merge 2 commits intomainfrom
feat/transaction-controller-is-internal

Conversation

@matthewwalsh0
Copy link
Copy Markdown
Member

Explanation

The TransactionController currently distinguishes "internal" (MetaMask-initiated) requests from "external" (dapp-initiated) requests by checking whether the request origin matches ORIGIN_METAMASK. Several validations in addTransaction and addTransactionBatch are skipped for internal requests:

  • Permitted-address check
  • EIP-7702 authorization rejection
  • Calls-with-data targeting an internal account
  • Duplicate batchId check
  • Batch size limit
  • Dapp-suggested gas fee handling and userFeeLevel selection

Inferring trust from the origin string couples the controller's security posture to whatever logic the consuming client happens to use when populating that field. A bug, refactor, or oversight further up the stack that lets a non-internal request reach the controller with origin: ORIGIN_METAMASK would silently bypass these validations.

This PR replaces that implicit check with an explicit, optional isInternal: boolean flag on both AddTransactionOptions and TransactionBatchRequest. The flag defaults to false, so the controller treats all requests as external unless the caller opts in. The flag is persisted on TransactionMeta and TransactionBatchMeta so downstream logic (notably userFeeLevel selection in gas-fees.ts) reads it directly rather than re-deriving trust from the origin.

The origin field is unchanged in shape and semantics — it still flows through to the ApprovalController as the display origin and is still attached to TransactionMeta for analytics, history, and dapp-suggested-gas display. It is simply no longer used as a trust signal.

BREAKING: validations are no longer gated on origin

Callers that previously relied on origin: ORIGIN_METAMASK (or an absent origin) to suppress these validations must now pass isInternal: true explicitly. Without that flag the controller will:

  • Reject EIP-7702 transactions
  • Enforce the permittedAddresses check on the from address
  • Enforce the batch size limit
  • Reject calls-with-data targeting an internal account
  • Reject duplicate batchIds
  • Treat the transaction as dapp-suggested for userFeeLevel

Internal MetaMask consumers (extension, mobile, and other core packages such as transaction-pay-controller, bridge-status-controller, perps-controller, and eip-5792-middleware) need to audit their call sites and pass isInternal: true for every request that genuinely originates inside MetaMask.

References

N/A

Changelog

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've highlighted breaking changes using the "BREAKING" category above as appropriate
  • I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes

…sInternal flag

Replace implicit `origin === ORIGIN_METAMASK` trust checks in
`addTransaction` and `addTransactionBatch` with an explicit, optional
`isInternal` flag (defaulting to `false`). The flag is persisted on
`TransactionMeta` and `TransactionBatchMeta` so downstream logic can
read it without re-deriving trust from the origin string.

BREAKING: Setting `origin` to `ORIGIN_METAMASK` (or omitting `origin`)
no longer skips the external-request validations. Callers that need
that behavior must now pass `isInternal: true` explicitly.
@matthewwalsh0
Copy link
Copy Markdown
Member Author

@metamaskbot publish-preview

@github-actions
Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.1.0-preview-156c8ccf7
@metamask-previews/accounts-controller@37.2.0-preview-156c8ccf7
@metamask-previews/address-book-controller@7.1.1-preview-156c8ccf7
@metamask-previews/ai-controllers@0.6.3-preview-156c8ccf7
@metamask-previews/analytics-controller@1.0.1-preview-156c8ccf7
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-156c8ccf7
@metamask-previews/announcement-controller@8.1.0-preview-156c8ccf7
@metamask-previews/app-metadata-controller@2.0.1-preview-156c8ccf7
@metamask-previews/approval-controller@9.0.1-preview-156c8ccf7
@metamask-previews/assets-controller@6.2.1-preview-156c8ccf7
@metamask-previews/assets-controllers@105.0.0-preview-156c8ccf7
@metamask-previews/authenticated-user-storage@1.0.0-preview-156c8ccf7
@metamask-previews/base-controller@9.1.0-preview-156c8ccf7
@metamask-previews/base-data-service@0.1.1-preview-156c8ccf7
@metamask-previews/bridge-controller@71.0.0-preview-156c8ccf7
@metamask-previews/bridge-status-controller@71.1.0-preview-156c8ccf7
@metamask-previews/build-utils@3.0.4-preview-156c8ccf7
@metamask-previews/chain-agnostic-permission@1.5.0-preview-156c8ccf7
@metamask-previews/chomp-api-service@2.0.0-preview-156c8ccf7
@metamask-previews/claims-controller@0.5.0-preview-156c8ccf7
@metamask-previews/client-controller@1.0.1-preview-156c8ccf7
@metamask-previews/compliance-controller@2.0.0-preview-156c8ccf7
@metamask-previews/composable-controller@12.0.1-preview-156c8ccf7
@metamask-previews/config-registry-controller@0.2.0-preview-156c8ccf7
@metamask-previews/connectivity-controller@0.2.0-preview-156c8ccf7
@metamask-previews/controller-utils@11.20.0-preview-156c8ccf7
@metamask-previews/core-backend@6.2.1-preview-156c8ccf7
@metamask-previews/delegation-controller@3.0.0-preview-156c8ccf7
@metamask-previews/earn-controller@12.0.0-preview-156c8ccf7
@metamask-previews/eip-5792-middleware@3.0.3-preview-156c8ccf7
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.0-preview-156c8ccf7
@metamask-previews/eip1193-permission-middleware@1.0.3-preview-156c8ccf7
@metamask-previews/ens-controller@19.1.1-preview-156c8ccf7
@metamask-previews/eth-block-tracker@15.0.1-preview-156c8ccf7
@metamask-previews/eth-json-rpc-middleware@23.1.3-preview-156c8ccf7
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-156c8ccf7
@metamask-previews/foundryup@1.0.1-preview-156c8ccf7
@metamask-previews/gas-fee-controller@26.1.1-preview-156c8ccf7
@metamask-previews/gator-permissions-controller@4.0.0-preview-156c8ccf7
@metamask-previews/geolocation-controller@0.1.2-preview-156c8ccf7
@metamask-previews/json-rpc-engine@10.2.4-preview-156c8ccf7
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-156c8ccf7
@metamask-previews/keyring-controller@25.2.0-preview-156c8ccf7
@metamask-previews/logging-controller@8.0.1-preview-156c8ccf7
@metamask-previews/message-manager@14.1.1-preview-156c8ccf7
@metamask-previews/messenger@1.2.0-preview-156c8ccf7
@metamask-previews/messenger-cli@0.2.0-preview-156c8ccf7
@metamask-previews/money-account-balance-service@0.2.0-preview-156c8ccf7
@metamask-previews/money-account-controller@0.1.0-preview-156c8ccf7
@metamask-previews/money-account-upgrade-controller@1.2.0-preview-156c8ccf7
@metamask-previews/multichain-account-service@8.0.1-preview-156c8ccf7
@metamask-previews/multichain-api-middleware@2.0.0-preview-156c8ccf7
@metamask-previews/multichain-network-controller@3.0.6-preview-156c8ccf7
@metamask-previews/multichain-transactions-controller@7.0.4-preview-156c8ccf7
@metamask-previews/name-controller@9.1.1-preview-156c8ccf7
@metamask-previews/network-controller@30.0.1-preview-156c8ccf7
@metamask-previews/network-enablement-controller@5.0.2-preview-156c8ccf7
@metamask-previews/notification-services-controller@23.1.0-preview-156c8ccf7
@metamask-previews/passkey-controller@1.0.0-preview-156c8ccf7
@metamask-previews/permission-controller@12.3.0-preview-156c8ccf7
@metamask-previews/permission-log-controller@5.1.0-preview-156c8ccf7
@metamask-previews/perps-controller@4.0.0-preview-156c8ccf7
@metamask-previews/phishing-controller@17.1.1-preview-156c8ccf7
@metamask-previews/polling-controller@16.0.4-preview-156c8ccf7
@metamask-previews/preferences-controller@23.1.0-preview-156c8ccf7
@metamask-previews/profile-metrics-controller@3.1.3-preview-156c8ccf7
@metamask-previews/profile-sync-controller@28.0.2-preview-156c8ccf7
@metamask-previews/ramps-controller@13.2.0-preview-156c8ccf7
@metamask-previews/rate-limit-controller@7.0.1-preview-156c8ccf7
@metamask-previews/react-data-query@0.2.0-preview-156c8ccf7
@metamask-previews/remote-feature-flag-controller@4.2.0-preview-156c8ccf7
@metamask-previews/sample-controllers@4.0.4-preview-156c8ccf7
@metamask-previews/seedless-onboarding-controller@9.1.0-preview-156c8ccf7
@metamask-previews/selected-network-controller@26.1.0-preview-156c8ccf7
@metamask-previews/shield-controller@5.1.1-preview-156c8ccf7
@metamask-previews/signature-controller@39.2.0-preview-156c8ccf7
@metamask-previews/snap-account-service@0.0.0-preview-156c8ccf7
@metamask-previews/social-controllers@2.2.0-preview-156c8ccf7
@metamask-previews/storage-service@1.0.1-preview-156c8ccf7
@metamask-previews/subscription-controller@6.1.2-preview-156c8ccf7
@metamask-previews/transaction-controller@65.0.0-preview-156c8ccf7
@metamask-previews/transaction-pay-controller@20.0.1-preview-156c8ccf7
@metamask-previews/user-operation-controller@41.2.0-preview-156c8ccf7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant