Skip to content

AI tool permission bypass: resolve_permission ignores conversation_id #97

@EVWorth

Description

@EVWorth

Summary

The resolve_permission function accepts a conversation_id parameter but never verifies that the pending approval request_id belongs to that conversation. Any conversation can approve/deny any pending AI tool permission request from any other conversation.

Location

src-tauri/crates/mas-ai/src/service.rs:533-549

pub async fn resolve_permission(
    &self,
    _conversation_id: &str,  // Accepted but never used for verification
    request_id: &str,
    allowed: bool,
) -> Result<(), AiError> {
    let sender = {
        let mut approvals = self.pending_approvals.lock().await;
        approvals.remove(request_id).ok_or(AiError::NoPendingPermission)?
    };
    // ...
}

Impact

  • User A in conversation tab 1 can approve/deny an AI tool execution request that originated from user/conversation tab 2
  • This bypasses the intent of per-conversation permission scoping
  • If multiple AI conversations are active simultaneously, permissions are not properly isolated

Fix

Verify that request_id belongs to conversation_id before resolving the permission:

let sender = {
    let mut approvals = self.pending_approvals.lock().await;
    let approval = approvals.remove(request_id)
        .ok_or(AiError::NoPendingPermission)?;
    if approval.conversation_id != conversation_id {
        return Err(AiError::PermissionConversationMismatch);
    }
    approval.sender
};

Note: this requires storing conversation_id alongside the sender in the pending_approvals map.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions