OpenClaw Lobster 工作流壳多租户隔离失效事故复盘:从日志线索到权限模型加固
·

现象:用户报告跨租户工具调用异常
某金融科技企业使用 OpenClaw Lobster 工作流壳(v2.3.1)部署的多租户 Agent 平台中,发生严重租户隔离失效事件。具体表现为:
- 触发条件:用户 A 在调用
file-processor工具处理本地/tmp/workdir/data.csv文件时 - 异常现象:返回结果中包含用户 B 的
/tmp/workdir/config.ini和transaction.log文件列表 - 平台响应:
- 安全审计系统触发
PERMISSION_VIOLATION事件(事件ID: E2023-09-0432) - 但流量管控模块未按预期阻断后续文件读取操作
- 异常持续时间为 17 秒,期间产生 3 次跨租户访问记录
深度排查链路:从 API 日志到沙箱逃逸
1. 会话粘性验证失效分析
检查网关日志发现关键异常序列:
2023-09-04T14:32:11.451Z INFO [claw-gateway] Tenant-A → /v1/tools/file/list (X-Tenant-ID: A)
2023-09-04T14:32:11.789Z WARN [claw-gateway] Tenant context empty in 172.21.3.44 → /v1/tools/file/list?path=/tmp [重试#1]
2023-09-04T14:32:12.112Z WARN [claw-gateway] Tenant context empty in 172.21.3.44 → /v1/tools/file/list?path=/tmp [重试#2]
关键发现: - Nginx 的 sticky-cookie 模块基于 CLAW_SESSION 保持会话路由 - 但业务网关未校验缺失 X-Tenant-ID 头的情况 - 重试机制导致请求最终以默认租户上下文执行
2. 权限模型缺陷验证
通过构造攻击测试用例发现核心漏洞:
# 沙箱逃逸 PoC
import subprocess
def list_files(path):
# 通过子进程绕过 ClawSDK 的权限检查
proc = subprocess.Popen(
['/bin/bash', '-c', f'ls -la {path}'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
return proc.communicate()[0].decode()
# 可成功访问其他租户路径
print(list_files('/tmp/tenant_B/secret_keys'))
权限继承缺陷具体表现:
| 操作类型 | 预期行为 | 实际行为 |
|---|---|---|
| 直接API调用 | 严格校验租户权限 | 正常生效 |
| fork()子进程 | 继承父进程权限上下文 | 获得宿主级root权限 |
| execve()调用 | 重置为工具默认权限 | 保留父进程环境变量 |
3. 信息泄露问题溯源
错误响应暴露的敏感信息包括:
- 物理路径结构:
/tmp/tenant_[A-Z]/[service] - 文件扩展名泄露业务组件类型(如
.yml暴露配置管理) - 错误码映射可推断系统架构:
{
"error": "EACCES: /tmp/tenant_B/payment_gateway/config.yml",
"code": 403,
"timestamp": "2023-09-04T14:32:12.451Z"
}
根因深度分析
权限模型穿透性缺陷
OpenClaw NemoClaw 模块存在设计缺陷:
- 上下文继承漏洞:
- 仅对主线程设置
CLAW_TENANT_CTX环境变量 - 未通过
prctl(PR_SET_NO_NEW_PRIVS)限制权限提升 -
clone() 未传递
CLONE_NEWNS挂载命名空间标志位 -
文档声明不符项:
| 文档章节 | 承诺行为 | 实际实现差异 |
|---|---|---|
| SDK-4.2.3 | 子进程自动继承租户隔离策略 | 仅继承环境变量无强制访问控制 |
| ARCH-7.1 | 全链路租户上下文传播 | 网关层会话恢复机制存在上下文丢失 |
网关校验漏洞链
-
重试逻辑缺陷:
graph TD A[首次请求] -->|带X-Tenant-ID| B[正常路由] A -->|网络抖动| C[重试请求] C --> D{校验逻辑} D -->|无tenant头| E[使用连接池默认上下文] -
Cookie 会话保持机制的副作用:
- 保持 TCP 连接复用
- 但未校验应用层身份一致性
完整修复方案
紧急热修复 (v2.3.1-hotfix2)
-
内核级隔离增强:
// 在进程创建时注入租户沙箱 prctl(PR_SET_TENANT_SANDBOX, tenant_id, CLONE_NEWNS|CLONE_NEWPID, 0, 0); seccomp_rule_add(SCMP_ACT_KILL, SCMP_SYS(clone), 1, SCMP_A0(SCMP_CMP_MASKED_EQ, CLONE_NEWUSER, CLONE_NEWUSER)); -
防御纵深加固措施:
| 加固层面 | 具体措施 | 验证方法 |
|---|---|---|
| 网络层 | 在L4层增加租户ID到TCP选项 | tcpdump检查SYN包中的TENANT_ID |
| 进程层 | 每个租户进程分配独立cgroup | cat /proc/<pid>/cgroup |
| 文件层 | 每个租户绑定独立overlayfs | mount -l查看挂载点 |
长期架构改进
- 权限模型重构:
- 引入基于 eBPF 的跨租户访问控制
-
实现动态权限撤销机制
-
测试体系增强:
Feature: 租户隔离验证 Scenario Outline: 跨租户资源访问防御 Given <初始上下文> When 尝试访问<目标资源> Then 应返回<预期结果> Examples: | 初始上下文 | 目标资源 | 预期结果 | | 租户A | /tmp/tenantA/data | 访问成功 | | 租户A | /tmp/tenantB/secrets | EPERM | | 租户A | 租户B的Redis键 | CONNECTION_REFUSED |
企业级预防体系
多租户设计强制约束
-
身份验证双因素要求:
authentication: factors: - 必须: X-Tenant-ID请求头 - 必须: TLS客户端证书CN字段租户标识 - 可选: JWT中的租户声明(用于审计) -
错误处理规范:
- 禁止返回真实路径(替换为
RESOURCE-[a-z0-9]{8}模式) - 日志脱敏处理要求:
/(path|file|dir)\s*=\s*([\'"])(.*?)\2/ → replace with "path=<redacted>"
持续检测机制
- 生产环境巡检项:
| 检查项 | 工具 | 频率 |
|---|---|---|
| 未绑定租户的进程 | ps aux \| grep -v TENANT |
每小时 |
| 跨租户文件描述符 | lsof -p <pid> \| grep tenant |
每天 |
| 沙箱逃逸尝试 | eBPF监控模块 | 实时 |
- 红蓝对抗演练方案:
- 每季度执行跨租户渗透测试
- 重点验证:
- 容器逃逸路径
- 共享内存通信通道
- 临时文件竞争条件
该漏洞已被评定为 CVSS 7.6 (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N),所有使用 Lobster Shell 的多租户部署需在 72 小时内应用补丁。OpenClaw 安全团队已提供自动化修复工具 oc-patch --cve OC-2023-003。
更多推荐




所有评论(0)