Access Control
A privileged action is reachable by the wrong caller because a check is missing, wrong, or built on a broken assumption.
Definition
Access-control vulnerabilities arise when a sensitive function (minting, upgrading, withdrawing, configuring) can be invoked by an actor who should not have permission — due to a missing modifier, a flawed role check, an unprotected initializer, or a guard whose assumption no longer holds.
How it works
- A function that mutates funds or configuration lacks a correct authorization check.
- An attacker calls it directly, or satisfies a guard that was never truly restrictive.
- The privileged action executes under attacker control (mint, upgrade, drain, or re-parameterize).
Vulnerable vs. fixed
// Missing access control — anyone can point the proxy at new logic.
function setImplementation(address impl) external {
implementation = impl;
}function setImplementation(address impl) external onlyOwner {
require(impl.code.length > 0, "not a contract");
implementation = impl;
emit ImplementationUpdated(impl);
}Detection steps
- Identify the sensitive value or permission the pattern can influence.
- Trace every path that can update or consume that value, including callbacks, routers, and privileged helpers.
- Reproduce the worst-case attacker flow with adversarial ordering, manipulated inputs, and maximum feasible capital.
Common signals
- Security depends on an assumption that is not enforced by code.
- A critical value is consumed immediately after an attacker-controlled interaction.
- A privileged call path crosses multiple contracts without one clear authorization boundary.
False positives
- The risky-looking operation is read-only and cannot affect settlement or authorization.
- The value is bounded by independent checks before it moves assets.
- All privileged entry points share the same tested guard and monitoring path.
Review questions
- Which invariant would fail if this input or caller were attacker-controlled?
- Can the attacker compose setup, trigger, settlement, and cleanup atomically?
- What independent check stops the exploit if the first guard is wrong?
Defensive checklist
- Gate every state-mutating privileged function with an explicit, tested check.
- Protect initializers against re-initialization and front-running.
- Prefer role-based access control with least privilege over ad-hoc address checks.
- Re-validate guards whose safety depends on protocol- or chain-level assumptions.
Related cases
- EIP-7702 Flashloan-Protection Bypass Case Research: When tx.origin == msg.sender Stopped Meaning EOADeFi Exploits
- KiloEx $7.5M Case Research: A Trusted Forwarder That Let Anyone Become the Price KeeperDeFi Exploits
- Cork $12M Case Research: HIYA Price Skew Meets an Unauthenticated Uniswap v4 HookDeFi Exploits
- UPCX $70M Case Research: When a ProxyAdmin Key Became the ProtocolOperational Security
- ZKsync $5M Case Research: Airdrop Admin Compromise and the sweepUnclaimed MintOperational Security
Related tools
Related glossary
