Summary
The Workspaces::Update interactor performs a global Workspace.find_by(id: context.id) lookup without scoping to the current user's workspaces, allowing an authenticated admin to update any workspace's attributes.
Vulnerable Code
File: server/app/interactors/workspaces/update.rb (line 10)
workspace = Workspace.find_by(id: context.id) # GLOBAL lookup — no user scoping
Controller: server/app/controllers/api/v1/workspaces_controller.rb (line 51-66)
authorize current_workspace on line 52 checks the Workspace-Id header workspace, not the target params[:id]
authorize @workspace on line 58 runs after the update is already committed to the database
Secure Comparison
Delete interactor (server/app/interactors/workspaces/delete.rb line 8):
workspace = context.user.workspaces.find_by(id: context.id) # USER-SCOPED — correct
The Find interactor (used by show) also correctly uses context.user.workspaces.find_by.
Additional Issue
workspace_params permits :organization_id (line 95), allowing workspace creation/update under arbitrary organizations.
Impact
An authenticated user with admin role can update ANY workspace by setting the Workspace-Id header to their own workspace and sending PUT /api/v1/workspaces/:target_id with the victim's ID.
Fix
Change line 10 in workspaces/update.rb to:
workspace = context.user.workspaces.find_by(id: context.id)
CWE
CWE-639: Authorization Bypass Through User-Controlled Key
Summary
The
Workspaces::Updateinteractor performs a globalWorkspace.find_by(id: context.id)lookup without scoping to the current user's workspaces, allowing an authenticated admin to update any workspace's attributes.Vulnerable Code
File:
server/app/interactors/workspaces/update.rb(line 10)Controller:
server/app/controllers/api/v1/workspaces_controller.rb(line 51-66)authorize current_workspaceon line 52 checks the Workspace-Id header workspace, not the targetparams[:id]authorize @workspaceon line 58 runs after the update is already committed to the databaseSecure Comparison
Delete interactor (
server/app/interactors/workspaces/delete.rbline 8):The Find interactor (used by
show) also correctly usescontext.user.workspaces.find_by.Additional Issue
workspace_paramspermits:organization_id(line 95), allowing workspace creation/update under arbitrary organizations.Impact
An authenticated user with admin role can update ANY workspace by setting the
Workspace-Idheader to their own workspace and sendingPUT /api/v1/workspaces/:target_idwith the victim's ID.Fix
Change line 10 in
workspaces/update.rbto:CWE
CWE-639: Authorization Bypass Through User-Controlled Key