CVE-2026-59233 Overview
CVE-2026-59233 is a missing authorization vulnerability in the permission management component of Roskus Prospero Flow CRM before version 5.2.1. The PermissionSaveController accepts a POST request to the permission save endpoint without validating whether the caller is entitled to modify role permissions. Any authenticated user can craft a request that grants any role, including their own, the complete set of application permissions. The flaw is tracked under CWE-639: Authorization Bypass Through User-Controlled Key.
Critical Impact
Authenticated low-privilege users can escalate to full administrative permissions by submitting a crafted POST request to the permission save endpoint, resulting in complete compromise of application confidentiality and integrity.
Affected Products
- Roskus Prospero Flow CRM versions prior to 5.2.1
- The vulnerable component is the PermissionSaveController in app/Http/Controllers/Permission/
- Fixed release: v5.5.3
Discovery Timeline
- 2026-08-10 - CVE-2026-59233 published to NVD
- 2026-08-10 - Last updated in NVD database
Technical Details for CVE-2026-59233
Vulnerability Analysis
The vulnerability resides in the save method of PermissionSaveController, which handles the POST request to the /permission endpoint. The controller accepts a roles array from the request body and iterates over each role_id => permissions pair, calling Role::findById($role_id)->syncPermissions($permissions). No authorization check verifies whether the requesting user has the administrative role required to alter permission-to-role mappings. Authentication alone is treated as sufficient, so any user with a valid session can invoke the endpoint.
Because the endpoint synchronizes the submitted permissions to the specified role, an attacker can grant their own role every permission defined by the application. This includes user management, data export, and configuration functions, resulting in full vertical privilege escalation from any authenticated account.
Root Cause
The root cause is the absence of an authorization gate on a state-changing endpoint. The controller relied on a generic Illuminate\Http\Request object and directly consumed unvalidated input. The EmailRequest form request in the same codebase only enforced Auth::check(), illustrating a pattern where authentication was conflated with authorization across the module.
Attack Vector
The attack is remotely exploitable over the network. An adversary logs in with any valid low-privilege account, then issues a crafted POST request to the permission save endpoint containing a roles[<role_id>][]=<permission> payload targeting their own role. Upon processing, the application grants the specified permissions without further checks. No user interaction is required beyond the attacker's own session.
// Patch: app/Http/Controllers/Permission/PermissionSaveController.php
namespace App\Http\Controllers\Permission;
use App\Http\Controllers\MainController;
+use App\Http\Requests\PermissionSaveRequest;
use Illuminate\Http\RedirectResponse;
-use Illuminate\Http\Request;
use Spatie\Permission\Models\Role;
class PermissionSaveController extends MainController
{
- public function save(Request $request): RedirectResponse
+ public function save(PermissionSaveRequest $request): RedirectResponse
{
- $roles = $request->roles;
-
- foreach ($roles as $role_id => $permissions) {
- Role::findById($role_id)->syncPermissions($permissions);
+ foreach ($request->validated()['roles'] as $role_id => $permissions) {
+ $role = Role::find($role_id);
+ if ($role) {
+ $role->syncPermissions($permissions);
+ }
}
- return redirect('/permission');
+ return redirect('/permission')->with('success', __('Permissions updated successfully'));
}
}
Source: GitHub Commit 86a7d65. The fix introduces a dedicated PermissionSaveRequest form request that centralizes authorization and validation before the controller touches the syncPermissions call.
Detection Methods for CVE-2026-59233
Indicators of Compromise
- POST requests to /permission originating from user accounts that do not belong to an administrative role.
- Sudden changes in the role_has_permissions table where a non-admin role suddenly receives high-value permissions.
- Web server access logs showing repeated roles[<id>][]= parameters submitted by the same session prior to privileged actions.
Detection Strategies
- Instrument application logs to record every invocation of PermissionSaveController::save with the authenticated user identity and the resulting role-permission diff.
- Compare database snapshots of role_has_permissions against a known-good baseline and alert on additions performed outside a change window.
- Correlate HTTP request telemetry with subsequent use of newly granted permissions by the same account within a short time window.
Monitoring Recommendations
- Forward web server, application, and database audit logs to a centralized analytics platform for correlation.
- Alert on any non-administrator account triggering the /permission POST route.
- Track first-time-seen permission assignments per role and flag deviations for review.
How to Mitigate CVE-2026-59233
Immediate Actions Required
- Upgrade Roskus Prospero Flow CRM to v5.5.3 or later, which incorporates the PermissionSaveRequest authorization fix.
- Audit the role_has_permissions table for unauthorized grants performed since the vulnerable version was deployed.
- Rotate credentials and revoke sessions for any account that may have escalated privileges through the flaw.
Patch Information
The upstream fix is delivered in commit 86a7d65 and released as Prospero Flow CRM v5.5.3. The patch replaces the unrestricted Request binding with a PermissionSaveRequest form request that enforces authorization and validation. Additional analysis is available in the CNA advisory for CVE-2026-59233.
Workarounds
- Restrict access to the /permission route at the reverse proxy or web application firewall so only administrative source identities can reach it.
- Add a middleware check on the route that verifies the caller possesses an administrative role before the controller executes.
- Temporarily disable the permission management UI and manage role assignments directly through the database until the patch is applied.
# Example Laravel route middleware guard until upgrade is possible
# routes/web.php
Route::post('/permission', [PermissionSaveController::class, 'save'])
->middleware(['auth', 'role:admin']);
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

