Skip to content

Account security hardening#39

Merged
chunter-cb merged 3 commits into
mainfrom
fix/account-security-hardening
Jul 15, 2026
Merged

Account security hardening#39
chunter-cb merged 3 commits into
mainfrom
fix/account-security-hardening

Conversation

@chunter-cb

@chunter-cb chunter-cb commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

Security hardening of the account and session policy, plus a repo reorg that moves the example policies to a top-level src/policies/ and extracts the unaudited example wallets into a separate repository (base/eip-8130-examples).

This branch also carries the doc-only commit documenting SessionPolicy spend-cap / approval limitations (b640d5c).

Security fixes

  • SessionPolicy — self-target bypass: reject a call scope whose target is the account itself at install (SelfTargetNotAllowed). The account is always an authorized caller of its own executeBatch, so letting a session key target it allowed re-entering with an arbitrary, unchecked batch that bypassed every policy dimension.
  • SessionPolicy — transferFrom source: enforce from == account, so a session key may only spend the account's own resources, not third-party allowances the account holds.
  • DefaultAccount — trusted executor authorization: _isAuthorizedCaller now (a) enforces the actor's expiry (previously silently ignored on the execution path) and (b) requires operational/sender authority — admin (scope 0) or SCOPE_SENDER without SCOPE_POLICY — mirroring AccountConfiguration.verifySignature, so a policy-gated actor can't get direct executeBatch.

Note: WebAuthnAuthenticator's requireUV = false was intentionally left unchanged. The DelegateAuthenticator recursive-delegation guard was explored but dropped from this PR (see the revert commit).

Repo reorg

  • Moved example policies src/examples/policies/*src/policies/* and re-pointed all test/script imports.
  • Extracted the unaudited example wallets (UpgradeableAccount, UpgradeableProxy, BackwardsCompatible4337Account) and their tests to base/eip-8130-examples; trimmed script/Deploy.s.sol and updated README.md / NatSpec references.

Test plan

  • forge build (core) passes
  • forge test (core) — 309 passing
  • Extracted wallets build + test green in the separate examples repo (46 passing)

Two under-documented sharp edges in the reference session policy:
- Value-moving selectors this policy cannot decode (increase/decreaseAllowance,
  ERC-721 safeTransferFrom, ERC-1155 transfers) are gated by the allowlist but
  NOT debited from a token's spend cap, so they bypass it if listed.
- `approve` is debited at grant time, but a standing ERC-20 allowance outlives
  the period and is pulled by a third party, so cross-period reuse can exceed a
  single period's cap.
Also documents the calldata-length handling (empty receive allowed, 1-3 bytes
rejected, 4+ treated as a selector). Doc-only.
…act example wallets

Security hardening:
- SessionPolicy: reject a call scope targeting the account itself at install
  (SelfTargetNotAllowed) — the account is always authorized to call its own
  executeBatch, so allowing a session key to target it would let the key
  re-enter with an arbitrary, unchecked batch that bypasses every policy check.
- SessionPolicy: enforce transferFrom `from == account`, so a session key can
  only spend the account's own resources, not third-party allowances it holds.
- DefaultAccount._isAuthorizedCaller: enforce TRUSTED_EXECUTOR actor expiry
  (previously silently ignored) and require operational (sender) authority —
  admin (scope 0) or SCOPE_SENDER without SCOPE_POLICY — mirroring the
  operational-actor definition in AccountConfiguration.verifySignature.
- DelegateAuthenticator: prevent cross-instance recursive delegation. The
  previous guard only rejected this exact instance, so two instances A/B could
  vouch for each other (A->B->A...). Now reject any nested authenticator that
  self-identifies via isDelegateAuthenticator(), enforcing a true single hop.

Repo reorg:
- Move example policies from src/examples/policies to src/policies (top level)
  and re-point test/script imports.
- Extract the unaudited example wallets (UpgradeableAccount, UpgradeableProxy,
  BackwardsCompatible4337Account) and their tests to a separate repository;
  trim Deploy.s.sol and update README/NatSpec accordingly.
Reverts the cross-instance recursive-delegation guard from this PR; the change
is not needed here.
@chunter-cb chunter-cb merged commit 45a4e35 into main Jul 15, 2026
7 checks passed
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