Skip to content

Systemic IDOR: bouncer() authorization check missing on most controller methods #2462

@lighthousekeeper1212

Description

@lighthousekeeper1212

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);
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions