fix(security): Constrain raw store and submitRequestToBackground exposure in state hooks #41958
fix(security): Constrain raw store and submitRequestToBackground exposure in state hooks #41958MajorLift wants to merge 4 commits into
store and submitRequestToBackground exposure in state hooks #41958Conversation
…h a curated surface Expose a read-only `store` facade (`getState` + `subscribe`, no `dispatch`), an allowlist-gated `submitRequestToBackground` wrapper (seed empty), and move `getPerpsStreamManager` under `stateHooks.services.perps`. Still gated on `METAMASK_DEBUG` and stripped from release builds.
|
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. |
Agentic/CDP automation hooks on `globalThis.stateHooks` now require both `METAMASK_DEBUG` and `METAMASK_AGENTIC_HOOKS` to be true at build time. Manual QA and general local debug builds no longer expose the automation surface unless the harness flag is opted in via `.metamaskrc`.
…k files `app/scripts/lib/setup-initial-state-hooks.*` and `/ui/index.js` are the bootstrap entry points where `globalThis.stateHooks` is populated; changes to either can broaden the debug/automation surface area without being obvious in review. Routing reviews through `@MetaMask/extension-platform` keeps the capability boundary visible.
✨ Files requiring CODEOWNER review ✨🔒 @MetaMask/extension-security-team (1 files, +4 -0)
|
|
Builds ready [7bbc499]
⚡ Performance Benchmarks (Total: 🟢 7 pass · 🟡 8 warn · 🔴 0 fail)
Bundle size diffs
|
store and submitRequestToBackground exposure in state hooks store and submitRequestToBackground exposure in state hooks
Reflects that the agentic hooks now require both `METAMASK_DEBUG` and `METAMASK_AGENTIC_HOOKS` to be true at build time.
Builds ready [91b53b4]
⚡ Performance Benchmarks (Total: 🟢 7 pass · 🟡 8 warn · 🔴 0 fail)
Bundle size diffs
|


Description
Constrains the agentic/CDP automation hooks added in #41648 (
globalThis.stateHooks.store,.submitRequestToBackground,.getPerpsStreamManager) so that a build-flag regression or unexpected dev-mode reachability cannot grant god-mode access to the full Redux store or background RPC surface.Compared to
#41648, autonomous agents will need to be set up with the following changes:METAMASK_AGENTIC_HOOKS=truein addition toMETAMASK_DEBUG=true.globalThis.stateHooks.store.getState()is available. Just.storeor.store.dispatchis blocked.globalThis.stateHooks.submitRequestToBackgroundcurrently doesn't allow anything so any methods needed by agents will have to be added to theAGENTIC_BACKGROUND_METHODSSet defined inui/index.js.globalThis.stateHooks.services.perps()instead ofglobalThis.stateHooks.getPerpsStreamManager().Scope:
storefacade. Replaces raw Redux store exposure with{ getState, subscribe }only — nodispatch, noreplaceReducer. Observation/wait-for-condition flows still work; arbitrary state mutation is removed.submitRequestToBackground. Wraps the real RPC with aSet<string>check againstAGENTIC_BACKGROUND_METHODS. The seed is empty — harness authors must open follow-up PRs listing specific methods with justification, making additions auditable. Non-allowlisted calls throw a clear error pointing at the allowlist location.stateHooks.services.perpsnamespace. MovesgetPerpsStreamManagerinto aservicesbucket, establishing the pattern for future UI-side service singletons (swaps, bridge, etc.) rather than growing flat top-level entries.METAMASK_AGENTIC_HOOKSbuild flag. Hooks now require bothMETAMASK_DEBUGandMETAMASK_AGENTIC_HOOKSat compile time. Manual QA and general local debug builds stop exposing the automation surface unless the flag is explicitly opted in via.metamaskrc. Both flags are DefinePlugin constants → dead-code-eliminated in release builds.app/scripts/lib/setup-initial-state-hooks.*and/ui/index.js— the two entry points whereglobalThis.stateHooksis populated — now route through@MetaMask/extension-platformreview, so future changes to the capability surface are visible to the team responsible for it.Why:
submitRequestToBackgroundis the full wire protocol to the background (keyring ops, transactions, networks, permissions). Exposing it raw onglobalThis— gated only by a single compile-time flag — is a significant blast radius if the gate ever misfires (supply-chain injection, debug leak to release, LavaMoat compartment escape in debug builds). Curating the surface and adding a second flag provides defense-in-depth without breaking the agentic harness (names/call-signatures preserved; behavior changes only at the capability boundary).Changelog
CHANGELOG entry: null
Related issues
Follows up on #41648 (original exposure) and #41687 (
PERPS_ENABLEDin main builds — the latter makesgetPerpsStreamManagerreachable in default debug builds, which motivated tightening this surface now).Manual testing steps
METAMASK_DEBUG=trueandMETAMASK_AGENTIC_HOOKS=true.window.stateHooks.store.getState()returns the Redux state.window.stateHooks.store.dispatchis undefined.window.stateHooks.submitRequestToBackground('anyMethod')throws with the "not in the agentic allowlist" message.window.stateHooks.services.perpsis thePerpsStreamManagersingleton.METAMASK_DEBUG=trueandMETAMASK_AGENTIC_HOOKS=false(or unset).window.stateHooks.store,.submitRequestToBackground, and.servicesare all undefined (block is dead-code-eliminated).Pre-merge author checklist
Pre-merge reviewer checklist