# Missing caller authorization on privileged functions

Privileged effect with no msg.sender/role binding, or a check keyed on the wrong identity

_Area: Smart contract access control and control flow. Seen in 197 disclosed reports; 3 confirmed bounties, median $4,515, range $2,000-$76,568; latest 2026-10-06. Updated 2026-10-23._

## How it works
A function that moves funds, changes ownership, or alters governance state assumes the caller is authorized but never proves it. The EVM has no ambient identity: any address can call any external function, so if the code does not compare `msg.sender` (or a role/owner) against the intended party before acting, any caller passes. A second shape is a check that exists but keys on the wrong identity: a target address instead of the caller [E3](https://bugbountylibrary.com/r/dhl%3A20260915-rsethsafemodule.md), a shared library registered as owner [E7](https://bugbountylibrary.com/r/dhl%3A20260901-reflexergeb.md), a router that itself holds the privileged role [E2](https://bugbountylibrary.com/r/dhl%3A20260921-theredvillage.md), a caller-supplied parameter used as the source of a transfer [E4](https://bugbountylibrary.com/r/dhl%3A20260915-bonfireswap.md)[E5](https://bugbountylibrary.com/r/dhl%3A20260909-etherfiatomicqueue.md), or a caller-supplied getter trusted as the authority [E1](https://bugbountylibrary.com/r/dhl%3A20261006-makerdaoflipkeeper.md).

## Where it shows up
- Fund-moving or upgrade functions with no owner/role/`msg.sender` guard before the effect [E1](https://bugbountylibrary.com/r/dhl%3A20261006-makerdaoflipkeeper.md)[E2](https://bugbountylibrary.com/r/dhl%3A20260921-theredvillage.md)[E7](https://bugbountylibrary.com/r/dhl%3A20260901-reflexergeb.md).
- `transferFrom`/`safeTransferFrom` where `from` is a parameter not bound to `msg.sender` [E4](https://bugbountylibrary.com/r/dhl%3A20260915-bonfireswap.md).
- A caller-supplied address used as the source of a pull or as a callback target, with no `== msg.sender`, signature, or registration [E5](https://bugbountylibrary.com/r/dhl%3A20260909-etherfiatomicqueue.md).
- Entrypoints that pull an arbitrary party's balance into a new order proxy without that party's signature or nonce [E6](https://bugbountylibrary.com/r/dhl%3A20260908-orderfactory.md).
- Check exists but validates the wrong identity: authorization by target address with `target == address(this)` trusted [E3](https://bugbountylibrary.com/r/dhl%3A20260915-rsethsafemodule.md); shared library/proxy-actions contract registered as owner, whose public functions then pass `msg.sender` checks [E7](https://bugbountylibrary.com/r/dhl%3A20260901-reflexergeb.md); router holding `_authorizeUpgrade` on a proxy it forwards to [E2](https://bugbountylibrary.com/r/dhl%3A20260921-theredvillage.md); drain trusting a caller-supplied `worker.vat()` getter [E1](https://bugbountylibrary.com/r/dhl%3A20261006-makerdaoflipkeeper.md).

## How to review
For every state-changing external function, name the intended caller and find the exact check enforcing it. The invariant: before any privileged effect, the acting identity must equal the authorized identity, and any address used as a transfer source or recipient must be bound to that identity, not to a caller-supplied value. Trace who the real `msg.sender` is at the check versus at the effect, especially through proxies, delegatecall, routers, and shared libraries. Confirm the permission checked matches the action performed. Grep targets: `external`/`public` functions, role modifiers (`onlyOwner`, `ds-auth`), every `from`/`to`/`recipient` parameter, any `address(this)` trust shortcut, and gates that only read a stored active flag (`getState`) [E6](https://bugbountylibrary.com/r/dhl%3A20260908-orderfactory.md).

## Variants seen
- Ungated selector on a keeper proxy trusting a caller-supplied worker getter [E1](https://bugbountylibrary.com/r/dhl%3A20261006-makerdaoflipkeeper.md).
- Ungated router relay forwarding `upgradeTo` to a proxy the router controls [E2](https://bugbountylibrary.com/r/dhl%3A20260921-theredvillage.md).
- Target-identity trust: self-call treated as authorized in a multicall router [E3](https://bugbountylibrary.com/r/dhl%3A20260915-rsethsafemodule.md).
- `transfer()` spending a victim's standing allowance [E4](https://bugbountylibrary.com/r/dhl%3A20260915-bonfireswap.md).
- Caller-supplied `solver` draining allowances [E5](https://bugbountylibrary.com/r/dhl%3A20260909-etherfiatomicqueue.md).
- `createOrderForBuyer` pulling an arbitrary buyer's balance [E6](https://bugbountylibrary.com/r/dhl%3A20260908-orderfactory.md).
- Shared library registered as SAFE owner, public `quitSystem` [E7](https://bugbountylibrary.com/r/dhl%3A20260901-reflexergeb.md).

## Impact and severity
Direct theft of funds and tokens [E1](https://bugbountylibrary.com/r/dhl%3A20261006-makerdaoflipkeeper.md)[E2](https://bugbountylibrary.com/r/dhl%3A20260921-theredvillage.md)[E3](https://bugbountylibrary.com/r/dhl%3A20260915-rsethsafemodule.md)[E4](https://bugbountylibrary.com/r/dhl%3A20260915-bonfireswap.md)[E5](https://bugbountylibrary.com/r/dhl%3A20260909-etherfiatomicqueue.md)[E6](https://bugbountylibrary.com/r/dhl%3A20260908-orderfactory.md)[E7](https://bugbountylibrary.com/r/dhl%3A20260901-reflexergeb.md) and proxy takeover [E2](https://bugbountylibrary.com/r/dhl%3A20260921-theredvillage.md). Severity is high when the effect is direct value transfer; worse when the missing check also lets the attacker choose the recipient or install an implementation.

## Evidence
- E1: https://bugbountylibrary.com/r/dhl%3A20261006-makerdaoflipkeeper.md
- E2: https://bugbountylibrary.com/r/dhl%3A20260921-theredvillage.md
- E3: https://bugbountylibrary.com/r/dhl%3A20260915-rsethsafemodule.md
- E4: https://bugbountylibrary.com/r/dhl%3A20260915-bonfireswap.md
- E5: https://bugbountylibrary.com/r/dhl%3A20260909-etherfiatomicqueue.md
- E6: https://bugbountylibrary.com/r/dhl%3A20260908-orderfactory.md
- E7: https://bugbountylibrary.com/r/dhl%3A20260901-reflexergeb.md
- E8: https://bugbountylibrary.com/r/c4%3A2026-04-k2%3AM-34.md
