Summary
Two authorization vulnerabilities allow users to manipulate resources in workspaces they don't own.
Affected Endpoints
1. Cross-Workspace User Removal
File: app/Http/Controllers/Workspaces/WorkspaceUsersController.php (line 48)
The destroy() method fetches users via User::find($userId) without verifying the target user belongs to the current workspace:
$user = User::find($userId); // No workspace scoping
$this->removeUserFromWorkspace->handle($user, $workspace);
The OwnsCurrentWorkspace middleware only validates the requester owns their current workspace, not that the $userId parameter belongs to it.
Secure pattern (line 27): $request->user()->currentWorkspace->users correctly scopes to current workspace.
Fix: Replace User::find($userId) with $workspace->users()->where('user_id', $userId)->firstOrFail().
2. Cross-Workspace Invitation Deletion
File: app/Http/Controllers/Workspaces/WorkspaceInvitationsController.php (line 42-44)
The destroy() method deletes any invitation by ID without checking workspace_id:
public function destroy(Invitation $invitation): RedirectResponse
{
$invitation->delete(); // No workspace_id validation
}
The OwnsCurrentWorkspace middleware is only applied to store (line 24), not destroy.
Fix: Validate $invitation->workspace_id === $request->user()->currentWorkspace()->id.
CWE
- CWE-639: Authorization Bypass Through User-Controlled Key
Severity
High - Cross-workspace user removal and invitation manipulation.
Summary
Two authorization vulnerabilities allow users to manipulate resources in workspaces they don't own.
Affected Endpoints
1. Cross-Workspace User Removal
File:
app/Http/Controllers/Workspaces/WorkspaceUsersController.php(line 48)The
destroy()method fetches users viaUser::find($userId)without verifying the target user belongs to the current workspace:The
OwnsCurrentWorkspacemiddleware only validates the requester owns their current workspace, not that the$userIdparameter belongs to it.Secure pattern (line 27):
$request->user()->currentWorkspace->userscorrectly scopes to current workspace.Fix: Replace
User::find($userId)with$workspace->users()->where('user_id', $userId)->firstOrFail().2. Cross-Workspace Invitation Deletion
File:
app/Http/Controllers/Workspaces/WorkspaceInvitationsController.php(line 42-44)The
destroy()method deletes any invitation by ID without checkingworkspace_id:The
OwnsCurrentWorkspacemiddleware is only applied tostore(line 24), notdestroy.Fix: Validate
$invitation->workspace_id === $request->user()->currentWorkspace()->id.CWE
Severity
High - Cross-workspace user removal and invitation manipulation.