T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- project/platforms/linux/src/session.ts:23
- Finding
- Application Access Requests Are Silently Auto-Approved<![CDATA[ ## Vulnerability Details **File Locations**: - `project/platforms/linux/src/session.ts:23-65` - `project/platforms/macos/src/session.ts:23-65` - `project/platforms/windows/src/session.ts:23-65` **Vulnerability Type**: Authorization and user-consent bypass **Risk Level**: High ### Vulnerable Code All three platform implementations contain the same automatic approval logic: ```ts function autoApprovePermission(req: CuPermissionRequest): CuPermissionResponse { const granted = req.apps .filter(app => app.resolved && !app.alreadyGranted) .map(app => ({ bundleId: app.resolved!.bundleId, displayName: app.resolved!.displayName, grantedAt: Date.now(), tier: app.proposedTier, })) const denied = req.apps .filter(app => !app.resolved) .map(app => ({ bundleId: app.requestedName, reason: 'not_installed' as const, })) return { granted, denied, flags: { ...DEFAULT_GRANT_FLAGS, ...req.requestedFlags, }, } } export function createSessionContext(): ComputerUseSessionContext { const state: State = { allowedApps: [], grantFlags: { ...DEFAULT_GRANT_FLAGS }, hiddenDuringTurn: new Set<string>(), } return { getAllowedApps: () => state.allowedApps, getGrantFlags: () => state.grantFlags, getUserDeniedBundleIds: () => [], getSelectedDisplayId: () => state.selectedDisplayId, getDisplayPinnedByModel: () => state.displayPinnedByModel ?? false, getDisplayResolvedForApps: () => state.displayResolvedForApps, getLastScreenshotDims: () => state.lastScreenshotDims, onPermissionRequest: async req => autoApprovePermission(req), ``` ### Technical Analysis The MCP computer-use framework treats `onPermissionRequest` as the authorization boundary through which a host should display a consent request and wait for the user to approve or deny access. The standalone session implementation instead routes the request directly to `autoApprovePermis ...[truncated 2879 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Replace `autoApprovePermission` with a host-mediated consent implementation that displays: - The resolved application identity. - The requested access tier. - The task-specific reason supplied with the request. - The capabilities available at that tier. 2. Require an explicit user action before returning any entry in `granted`. If the standalone runtime cannot display a trusted consent interface, fail closed and return a denial. 3. Do not allow the requesting Agent to choose the final access tier unilaterally. Permit the user to reduce the proposed tier or reject individual applications. 4. Implement and persist user-denied application identifiers rather than returning an unconditional empty list from `getUserDeniedBundleIds`. 5. Make grants short-lived and scoped to the active session or task. Clear them on process restart, task completion, lock release, or a user-triggered revocation event. 6. Preserve hard policy denials for sensitive applications and consider extending them to credential managers, system settings, security tools, terminals, IDEs, and financial applications. 7. Add automated tests confirming that: - No resolved application is granted without an explicit approval response. - Denied applications remain denied. - Approval cancellation fails closed. - An unavailable or crashed consent UI results in denial. - Requested tiers cannot exceed the tier selected by the user. 8. Clearly document the consent boundary and avoid describing access as approval-gated until the standalone host actually presents and enforces a user approval workflow. ]]>
