2.8 KiB
2.8 KiB
title, type, tags, sources, last_updated
| title | type | tags | sources | last_updated | |||||
|---|---|---|---|---|---|---|---|---|---|
| Access Control(访问控制) | concept |
|
|
2026-05-30 |
Aliases
- Access Control
- 访问控制 / 权限控制
Definition
访问控制(Access Control)定义谁可以执行合约中的哪些操作。访问控制缺陷是智能合约最常见的高危漏洞类别之一,错误的权限配置可直接导致资金被盗或协议被永久阻塞。
Key Vulnerability Classes
1. Missing Access Modifier(缺失访问修饰符)
// VULNERABLE: withdraw() 没有访问控制,任何人都能调用
function withdraw() external {
uint256 amount = balances[msg.sender];
(bool success,) = msg.sender.call{value: amount}("");
require(success);
balances[msg.sender] = 0;
}
2. Wrong Access Modifier(错误的访问修饰符)
// VULNERABLE: 应该是 onlyOwner,但误写成 external
// 导致任何人都能调用紧急停止
function emergencyStop() external {
paused = true;
}
3. Unprotected initialization(未保护的初始化)
// VULNERABLE: initialize() 没有 initializer 修饰符
// 攻击者可抢先调用,劫持合约
function initialize(address _owner) external {
owner = _owner;
}
4. Proxy Storage Collision(代理存储冲突)
升级型代理合约中,新实现版本的存储布局与旧版本不兼容,导致状态变量被覆盖:
// Implementation V1
uint256 public totalValue; // slot 0
// Implementation V2 — 新增变量导致 slot 0 被覆盖
address public newAdmin; // slot 0 ← 覆盖了 totalValue!
uint256 public totalValue; // slot 1
5. Role Renunciation Hijack(角色放弃劫持)
允许 admin 放弃角色后无人能恢复,导致协议永久不可升级。
Audit Checklist
- 所有特权函数都有显式访问修饰符
- Admin 角色不能自我授予(需要多签或时间锁)
initialize()只能调用一次(initializer 修饰符)- 实现合约构造函数中有
_disableInitializers() _authorizeUpgrade()受 owner/多签/时间锁保护- 存储布局在版本间兼容(无 slot 碰撞)
- 无
delegatecall到用户可控地址
Severity Classification
- Critical:缺失关键特权函数的访问控制,可直接导致资金损失
- High:条件性权限提升(需要特定状态),或协议可被 admin 永久阻塞
- Medium:缺失非关键函数的访问控制
- Low:缺少事件日志、代码规范问题
Related Concepts
- Reentrancy:缺失访问控制会加剧重入攻击影响
- Proxy-Upgrade:代理升级模式引入额外访问控制风险
- OpenZeppelin 的 AccessControl 库是标准安全实现