# Token guardian protection doesn’t account for approved operators in approve()

LensHandles/LensProfiles approve() only checks msg.sender's token guardian, so approved operators can still set approvals on guardian-protected tokens.

- Payout: Audit contest
- Severity: medium
- Program: Lens Protocol
- Found by: MiloTruck
- Disclosed: 2023-12-11
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2023-07-lens#m-08
- Library page: https://bugbountylibrary.com/r/c4%3A2023-07-lens%3AM-08
- Tags: area:web3 domain:web3 impact:integrity kind:contest platform:code4rena sev:medium tech:evm tech:solidity vuln:access-control vuln:auth-bypass

**Target:** LensHandles/LensProfiles ERC-721 approve() override
**Root cause:** The approve() override checks _hasTokenGuardianEnabled(msg.sender) instead of the token owner, so an approved operator (who can call approve per ERC-721) bypasses the guardian check.
**Steps:**
1. Alice calls `DANGER__disableTokenGuardian()` then `setApprovalForAll(BOB, true)`.
2. Alice calls `enableTokenGuardian()`.
3. Bob calls `DANGER__disableTokenGuardian()` for himself.
4. Bob calls `lensHandles.approve(address(0x1337), tokenId)` on Alice's token; it succeeds despite Alice's guardian being enabled.
**How found:** Read the README's token guardian guarantee, then compared the approve() override's msg.sender check against OpenZeppelin's ERC-721 approve which permits approved-for-all operators to call it.
**Exploitation:** An operator previously approved by the victim, after disabling their own guardian, calls approve() to grant a third party allowance over the victim's guardian-protected token, enabling later transferFrom.
**Insight:** When overriding ERC-721 approve() for owner-side protections, remember callers include approved-for-all operators; check _ownerOf(tokenId) rather than msg.sender.

