Summary
Multiple controllers use findOrFail($id) without checking bouncer()->getAuthorizedUserIds() to verify the current user has access to the resource. The LeadController::view() method correctly implements this check, but sibling methods and other controllers skip it.
Details
LeadController (1-of-N inconsistency)
File: packages/Webkul/Admin/src/Http/Controllers/Lead/LeadController.php
Vulnerable - edit() (line 209):
public function edit(int $id): View
{
$lead = $this->leadRepository->findOrFail($id);
return view('admin::leads.edit', compact('lead'));
}
Protected - view() (line 219):
public function view(int $id)
{
$lead = $this->leadRepository->findOrFail($id);
$userIds = bouncer()->getAuthorizedUserIds();
if ($userIds && ! in_array($lead->user_id, $userIds)) {
return redirect()->route('admin.leads.index');
}
return view('admin::leads.view', compact('lead'));
}
Also missing in LeadController: update(), updateAttributes(), updateStage(), addProduct(), removeProduct().
Also affected:
PersonController (Contact/Persons/PersonController.php): show() and edit() have no bouncer check. search() (line 120) and PersonDataGrid (line 35) correctly scope by user_id.
QuoteController (Quote/QuoteController.php): edit(), update(), print(), destroy() have no bouncer check.
ActivityController (Activity/ActivityController.php): edit(), update(), download() have no bouncer check.
Impact
When bouncer permissions are set to 'Individual' or 'Group' (not 'All'), users can still access any resource via direct endpoint access. The DataGrid list views correctly scope, but direct show/edit/update/delete bypasses this.
Recommended Fix
Add bouncer check to all methods accessing user-scoped resources:
protected function authorizeResource($resource)
{
if ($userIds = bouncer()->getAuthorizedUserIds()) {
if (! in_array($resource->user_id, $userIds)) {
abort(403);
}
}
}
Summary
Multiple controllers use
findOrFail($id)without checkingbouncer()->getAuthorizedUserIds()to verify the current user has access to the resource. TheLeadController::view()method correctly implements this check, but sibling methods and other controllers skip it.Details
LeadController (1-of-N inconsistency)
File:
packages/Webkul/Admin/src/Http/Controllers/Lead/LeadController.phpVulnerable -
edit()(line 209):Protected -
view()(line 219):Also missing in LeadController:
update(),updateAttributes(),updateStage(),addProduct(),removeProduct().Also affected:
PersonController (
Contact/Persons/PersonController.php):show()andedit()have no bouncer check.search()(line 120) and PersonDataGrid (line 35) correctly scope by user_id.QuoteController (
Quote/QuoteController.php):edit(),update(),print(),destroy()have no bouncer check.ActivityController (
Activity/ActivityController.php):edit(),update(),download()have no bouncer check.Impact
When bouncer permissions are set to 'Individual' or 'Group' (not 'All'), users can still access any resource via direct endpoint access. The DataGrid list views correctly scope, but direct show/edit/update/delete bypasses this.
Recommended Fix
Add bouncer check to all methods accessing user-scoped resources: