T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- runtime/src/config-manager.js:413
- Finding
- Cloud-Controlled Recursive Workspace Deletion Uses an Insufficient Path Boundary Check<![CDATA[ ## Vulnerability Details **File Location**: `runtime/src/companion-executor.js:162-180` and `runtime/src/config-manager.js:413-434` **Vulnerability Type**: Inadequate authorization and path validation for remote destructive operations **Risk Level**: High ### Vulnerable Code ```js // runtime/src/companion-executor.js:162-180 if (operation.type === 'delete_agent') { const payload = operation.payload || {}; const removeInfo = this.configManager.removeAgentFromConfig({ openclawAgentId: payload.openclawAgentId, workspacePath: payload.workspacePath, name: payload.name, }); const preserveWorkspace = payload.preserveWorkspace === true; const workspaceInfo = preserveWorkspace ? { deleted: false, preserved: true, reason: 'preserve_workspace_requested', workspacePath: payload.workspacePath || null, } : this.configManager.deleteWorkspace(payload.workspacePath); ``` ```js // runtime/src/config-manager.js:413-434 deleteWorkspace(workspacePath) { if (!workspacePath) { return { deleted: false, reason: 'missing_workspace_path' }; } const resolvedPath = this.resolveHomePath(workspacePath); if (!fs.existsSync(resolvedPath)) { return { deleted: false, reason: 'workspace_missing', workspacePath: resolvedPath }; } const normalizedPath = resolvedPath.replace(/\\/g, '/'); const looksLikeOpenClawWorkspace = normalizedPath.includes('/.openclaw/') || normalizedPath.includes('/openclaw/') || path.basename(resolvedPath).startsWith('workspace-'); if (!looksLikeOpenClawWorkspace) { return { deleted: false, reason: 'workspace_path_not_safe', workspacePath: resolvedPath }; } fs.rmSync(resolvedPath, { recursive: true, force: true }); return { deleted: true, workspacePath: resolvedPath }; } ``` ### Technical Analysis The persistent daemon obtains pending operations and their payloads from the Ekybot cloud. For a `delete_agent` operation, the cloud-provided `workspa ...[truncated 2259 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Define one explicit managed-workspace root, such as `~/.openclaw/managed-workspaces`. 2. Resolve both the approved root and deletion target with `fs.realpathSync()` before performing any operation. 3. Verify containment using `path.relative()`: - Reject absolute relative results. - Reject `..` and paths beginning with `../`. - Reject deletion of the workspace root itself. 4. Reject symbolic links at the target and at relevant path components, or use filesystem operations that cannot traverse them unexpectedly. 5. Verify that the target belongs to the locally recorded managed agent rather than trusting the remote `workspacePath`. 6. Default `preserveWorkspace` to true and require an explicit local confirmation or separately authorized destructive-action token before deleting files. 7. Maintain recoverable backups or move workspaces to a quarantine/trash directory instead of immediately deleting them. 8. Log the canonical target and operation identifier before deletion, without exposing credentials. 9. Add tests covering traversal, symlinks, `.openclaw` parent directories, unrelated `workspace-*` directories, filesystem roots, and malformed paths. ]]>
