用途
该技能用于防止用户访问其无权访问的数据或操作。资料指出,失效的访问控制是 OWASP A01,因为它是最常见的严重 Web 漏洞:用户 A 可以读取用户 B 的发票、更改另一个租户的设置,或通过猜测 ID 调用管理端点。
核心原则
- 默认拒绝——除非显式标记为公开,否则没有路由是公开的
- 服务端检查授权——永远不要信任隐藏按钮或客户端检查
- 按用户或租户限定每个查询——永远不要仅凭原始 ID 获取
- 使用集中式策略——避免分散的 if (user.role === 'admin') 检查
- 将角色与权限分离——角色是捆绑包,权限是操作
- 审计敏感决策——记录被拒绝和特权操作
漏洞模式:IDOR
资料给出不安全直接对象引用(IDOR)的错误与正确写法。
错误示例:
app.get('/api/invoices/:id', async (req, res) => {
const invoice = await db.invoice.findUnique({ where: { id: req.params.id } });
res.json(invoice); // Any logged-in user can read any invoice by guessing ID
});
正确示例:
app.get('/api/invoices/:id', requireAuth, async (req, res) => {
const invoice = await db.invoice.findFirst({
where: {
id: req.params.id,
tenantId: req.user.tenantId,
},
});
if (!invoice) return res.status(404).json({ error: 'Not found' });
res.json(invoice);
});
当不应暴露资源是否存在时,返回 404 而不是 403。
企业授权模型
对每个受保护操作使用以下决策顺序:
- 用户是否已认证?
- 账户是否处于活动状态且未被暂停?
- 用户是否在被访问的租户/工作区内?
- 用户是否具有所需权限?
- 资源是否属于用户的租户?
- 是否存在对象级条件?(所有者、分配用户、审批状态)
- 该操作是否应记录审计日志?
RBAC 模式
资料给出基于角色的访问控制示例:
type Role = 'owner' | 'admin' | 'member' | 'viewer';
type Permission =
| 'invoice:read'
| 'invoice:create'
| 'invoice:update'
| 'invoice:delete'
| 'user:invite'
| 'billing:manage';
const ROLE_PERMISSIONS: Record<Role, Permission[]> = {
owner: ['invoice:read', 'invoice:create', 'invoice:update', 'invoice:delete', 'user:invite', 'billing:manage'],
admin: ['invoice:read', 'invoice:create', 'invoice:update', 'user:invite'],
member: ['invoice:read', 'invoice:create'],
viewer: ['invoice:read'],
};
function hasPermission(role: Role, permission: Permission): boolean {
return ROLE_PERMISSIONS[role]?.includes(permission) ?? false;
}
ABAC 模式
基于属性的访问控制增加对象级条件:
interface AuthContext {
userId: string;
tenantId: string;
role: Role;
permissions: Permission[];
}
interface Invoice {
id: string;
tenantId: string;
ownerId: string;
status: 'draft' | 'sent' | 'paid';
}
function canUpdateInvoice(user: AuthContext, invoice: Invoice): boolean {
if (invoice.tenantId !== user.tenantId) return false;
if (!hasPermission(user.role, 'invoice:update')) return false;
if (invoice.status === 'paid') return false;
if (user.role === 'member' && invoice.ownerId !== user.userId) return false;
return true;
}
各框架实现模式
Node.js / Express 中间件
资料提供 requireAuth、requirePermission 中间件以及路由示例,权限检查失败时记录审计日志并返回 403。
Cloudflare Workers 模式
资料提供 requireAuth、requirePermission 以及按租户限定查询的 getTenantScopedInvoice 示例。
Laravel Policy 模式
资料提供 InvoicePolicy 的 view 与 update 方法,以及控制器中 authorize 调用。并强调始终为路由模型绑定或全局作用域添加租户限定:
protected static function booted()
{
static::addGlobalScope('tenant', function (Builder $builder) {
if (auth()->check()) {
$builder->where('tenant_id', auth()->user()->tenant_id);
}
});
}
Python FastAPI 模式
资料提供 require_permission 依赖以及按租户限定查询的 update_invoice 示例。
数据库行级安全
对于 PostgreSQL,在数据库层也强制租户隔离:
ALTER TABLE invoices ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON invoices
USING (tenant_id = current_setting('app.current_tenant_id')::uuid);
-- Set this per request/transaction
SELECT set_config('app.current_tenant_id', 'tenant-uuid-here', true);
RLS 不能替代应用授权,但当开发者忘记租户过滤时,它可以减少影响范围。
管理路由保护
管理路由需要更强的控制:
- 将 admin:* 权限与用户角色分离
- 管理操作要求 MFA
- 敏感变更要求近期认证
- 审计记录所有管理读写
- 永远不要依赖前端路由隐藏
- 尽可能阻止来自未知 IP 的管理访问
资料给出 requireAdminAction 组合中间件示例。
访问控制审计清单
- 每个受保护路由都有认证中间件
- 每个敏感操作都有权限检查
- 每个资源查询都按 tenantId 或 userId 限定
- 租户拥有的资源不使用原始 ID 查找
- 用户无法通过更改 URL ID 访问另一个租户的数据
- 前端检查在服务端重复
- 管理路由要求显式管理权限
- 管理操作要求 MFA 或近期重新认证
- 被拒绝的访问尝试记录审计日志
- 未授权时不泄露资源是否存在
- 角色和权限集中定义
- 多租户应用存在数据库 RLS 或等效防护
- 测试覆盖跨租户访问尝试
必需测试
每个多租户项目必须包含这些测试,资料给出示例:
it('prevents user from reading another tenant invoice', async () => {
const tenantAInvoice = await createInvoice({ tenantId: 'tenant-a' });
const tenantBUser = await createUser({ tenantId: 'tenant-b' });
const response = await request(app)
.get(`/api/invoices/${tenantAInvoice.id}`)
.set('Authorization', `Bearer ${tokenFor(tenantBUser)}`);
expect(response.status).toBe(404);
});
PDPA 2024 后果
资料指出,失效的访问控制是造成可报告个人数据泄露的最快方式。如果一个客户可以访问另一个客户的个人数据,则开发者未能实现基本授权和租户隔离。根据 PDPA 2024 Seksyen 5(1) 和 5(2),这可能触发最高 RM1,000,000 罚款或 3 年监禁。
适用场景与限制
该技能适用于需要防止越权访问、多租户数据隔离、管理路由保护和安全审计的 Web 应用开发。资料未提供该技能的安装命令、收费信息、平台支持范围或具体使用步骤,这些内容暂未提供。