### 漏洞概述 该漏洞涉及OpenClaw项目中sandbox模块的CDP(Chrome DevTools Protocol)源范围限制问题。默认情况下,CDP源范围未正确限制,可能导致安全风险。 ### 影响范围 - **受影响模块**:sandbox模块 - **具体影响**:CDP源范围未正确限制,可能导致未授权访问或数据泄露。 ### 修复方案 1. **默认启用CDP源范围限制**: - 在`scripts/sandbox-browser-entrypoint.sh`中,默认设置`CDP_SOURCE_RANGE`为`127.0.0.1/32`。 - 如果未设置`CDP_SOURCE_RANGE`,则拒绝启动socat中继。 2. **自动推导CDP源范围**: - 从Docker网络网关IP自动推导CDP源范围。 - 如果无法推导,则拒绝启动socat中继。 3. **代码修改**: - 在`src/agents/sandbox/browser.create.test.ts`中添加测试用例,确保CDP源范围限制正确应用。 - 在`src/agents/sandbox/browser.ts`中实现CDP源范围的自动推导和限制逻辑。 - 在`src/agents/sandbox/constants.ts`中更新默认配置,确保CDP源范围限制生效。 ### POC代码 ```typescript // src/agents/sandbox/browser.create.test.ts it("auto-derives CDP source range from Docker network gateway", async () => { dockerMocks.readDockerNetworkGateway.mockResolvedValue("172.21.0.1"); await expect( ensureSandboxBrowser({ scopeKey: "session:test", workspaceDir: "/tmp/workspace", agentWorkspaceDir: "/tmp/workspace", cfg: buildConfig(false), }) ).resolves.toMatchObject({ envEntries: expect.arrayContaining([ "OPENCLAW_BROWSER_CDP_SOURCE_RANGE=172.21.0.1/32", ]), }); }); it("uses explicit cdpSourceRange over auto-derived gateway", async () => { dockerMocks.readDockerNetworkGateway.mockResolvedValue("172.21.0.1"); const cfg = buildConfig(false); cfg.browser.cdpSourceRange = "10.0.0.0/24"; await expect( ensureSandboxBrowser({ scopeKey: "session:test", workspaceDir: "/tmp/workspace", agentWorkspaceDir: "/tmp/workspace", cfg, }) ).resolves.toMatchObject({ envEntries: expect.arrayContaining([ "OPENCLAW_BROWSER_CDP_SOURCE_RANGE=10.0.0.0/24", ]), }); }); it("rejects IPv6-only gateway (relay binds IPv4)", async () => { dockerMocks.readDockerNetworkGateway.mockResolvedValue("fd12::1"); await expect( ensureSandboxBrowser({ scopeKey: "session:test", workspaceDir: "/tmp/workspace", agentWorkspaceDir: "/tmp/workspace", cfg: buildConfig(false), }) ).rejects.toThrow("Cannot derive CDP source range"); }); it("throws when CDP source range cannot be derived", async () => { dockerMocks.readDockerNetworkGateway.mockResolvedValue(null); await expect( ensureSandboxBrowser({ scopeKey: "session:test", workspaceDir: "/tmp/workspace", agentWorkspaceDir: "/tmp/workspace", cfg: buildConfig(false), }) ).rejects.toThrow("Cannot derive CDP source range"); }); it("requires explicit cdpSourceRange for non-bridge network drivers", async () => { dockerMocks.readDockerNetworkDriver.mockResolvedValue("macvlan"); dockerMocks.readDockerNetworkGateway.mockResolvedValue("172.21.0.1"); await expect( ensureSandboxBrowser({ scopeKey: "session:test", workspaceDir: "/tmp/workspace", agentWorkspaceDir: "/tmp/workspace", cfg: buildConfig(false), }) ).rejects.toThrow("Cannot derive CDP source range"); // Gateway helper should not have been called for non-bridge networks. expect(dockerMocks.readDockerNetworkGateway).not.toHaveBeenCalled(); }); it("uses loopback range for networkmode none (no IPAM gateway, no peer risk)", async () => { dockerMocks.readDockerNetworkGateway.mockResolvedValue(null); const cfg = buildConfig(false); cfg.browser.network = "none"; const result = await ensureSandboxBrowser({ scopeKey: "session:test", workspaceDir: "/tmp/workspace", agentWorkspaceDir: "/tmp/workspace", cfg, }); expect(result).toBeDefined(); const createArgs = findDockerArgCall(dockerMocks.execDocker.mock.calls, "create"); const envEntries = collectDockerFlagValues(createArgs ?? [], "-e"); expect(envEntries).toContain("OPENCLAW_BROWSER_CDP_SOURCE_RANGE=127.0.0.1/32"); }); ``` ### 总结 该漏洞通过默认启用CDP源范围限制和自动推导CDP源范围来修复,确保sandbox模块的安全性。相关代码修改和测试用例已添加到项目中。