Namespace model switching spoofable
Summary
The find_root_namespace helper method in the Duo Workflows API has two security vulnerabilities that allow unauthorized access to namespace-level AI model settings:
-
Missing authorization check: Uses
find_namespaceinstead offind_namespace!, allowing users to access any namespace without permission verification - No context validation: Users can specify any namespace they have read access to, not just namespaces relevant to their current workflow context
Details
ee/lib/api/ai/duo_workflows/workflows.rb
def find_root_namespace
# The IDE sends namespace data via the header, while the web agentic chat UI
# sends it as a query param.
# The IDE only sends the namespace_id of the project's
# immediate group, so we have to find the root_ancestor separately.
namespace_id = params[:root_namespace_id].presence || headers['X-Gitlab-Namespace-Id'].presence
return unless namespace_id
namespace = find_namespace(namespace_id) # ⚠️ No authorization check
namespace&.root_ancestor
end
Vulnerability 1: Missing Authorization Check
Issue: The code uses find_namespace(namespace_id) which, according to the helper documentation in lib/api/helpers.rb, explicitly states:
find_namespacereturns the namespace regardless of user access level on the namespace
Impact: A malicious user can provide any root_namespace_id (via query parameter or X-Gitlab-Namespace-Id header) to access model selection settings for namespaces they don't have permission to read.
Vulnerability 2: No Context Validation
Issue: Even with authorization checks, users can specify any namespace they have read access to, regardless of whether that namespace is contextually relevant to their current workflow.
Impact: Users can exploit model settings from unrelated namespaces they happen to have access to, potentially:
- Using premium AI models configured in other organizations
- Bypassing their own organization's model restrictions
- Accessing model configurations they shouldn't be using in the current context