# unauthorize() can be front-run so that the malicious authorized user would get their authority back

Drips Caller lets an authorized delegate call authorize() via callAs, so a malicious delegate front-runs unauthorize() by adding an accomplice who re-authorizes them.

- Payout: Contest reward
- Severity: medium
- Program: Drips Protocol
- Credited: 0xA5DF
- Disclosed: 2023-03-10
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-01-drips-findings/issues/163
- Library page: https://bugbountylibrary.com/r/c4%3A2023-01-drips%3AM-02
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:race-window vuln:access-control vuln:business-logic

**Target:** Caller contract authorization (authorize/unauthorize/callAs)
**Root cause:** authorize() resolves the acting user via _msgSender(), so a delegated user calling through callAs() can add new authorized addresses on the original user's behalf.
**Steps:**
1. Alice authorizes Bob via `authorize(bob)`.
2. Alice submits `unauthorize(bob)`; Bob observes it in the mempool.
3. Bob front-runs with `callAs(alice, caller, abi.encodeWithSelector(Caller.authorize.selector, eve))`, adding Eve.
4. Alice's `unauthorize(bob)` executes, removing only Bob.
5. Bob calls `callAs(alice, caller, authorize(bob))` through Eve's account, regaining authority.
**How found:** Code reading of Caller's authorize() using _msgSender() combined with callAs delegation, realizing the delegated caller can invoke authorize on the original user's behalf and that revoke is a single-address operation vulnerable to ordering.
**Exploitation:** Malicious delegate watches for the revoke tx, outbids gas (or bribes validator via block.coinbase) to land an authorize(accomplice) tx first, then uses the accomplice to re-authorize themselves and continue draining/redirecting the victim's drips.
**Escalation:** Repeat the front-run each time the victim revokes, sustaining an indefinite griefing/ongoing theft battle; victim must batch-revoke all authorized addresses atomically.
**Insight:** When a delegation primitive lets the delegate invoke the same access-control functions (grant/revoke) as the principal, check whether revocation is atomic across all delegates; single-address revoke is front-runnable by re-granting via an accomplice.
