Overview
In CVE-2026-31843, the goodoneuz/pay-uz Laravel package versions ≤ 2.2.24 contains a critical object-level authorization flaw. The vulnerable /payment/api/editable/update endpoint is exposed via Route::any() without authentication or authorization checks, allowing any caller to reach this function. User-controlled input can be written directly to executable PHP files in the web root using file_put_contents(), and these files are later loaded via require() during normal payment processing, leading to remote code execution under the application's default behavior. The vendor’s claim about the payment secret token is unrelated to this vulnerability and does not mitigate the risk.
This vulnerability represents a broken object level authorization scenario because an unauthenticated actor can modify a resource (the payment hook file) that directly affects application behavior. By bypassing access controls, an attacker can implant arbitrary PHP code that the application subsequently executes, gaining control over the server and potentially exfiltrating data or creating backdoors.
The real-world impact can be severe: RCE on the hosting environment, persistence mechanisms within the payment workflow, and broad access to application data. Mitigations require not only patching authentication and authorization but also changing how dynamic, code-like inputs are handled-specifically avoiding writing executable code from user input and using safe storage and loading patterns in Laravel.
Remediations should also include updating any vulnerable dependencies and adding tests to ensure that routes handling sensitive configuration or plugin-like hooks are never writable by unauthenticated callers. This guidance references CVE-2026-31843 to illustrate the risks of improper object-level access control in Laravel apps and demonstrates concrete steps to eliminate the insecure pattern.
Affected Versions
≤ 2.2.24
Code Fix Example
Laravel API Security Remediation
/* VULNERABLE pattern (no auth, writes user input to PHP file) */
Route::any('/payment/api/editable/update', function (Request $request) {
$hook = $request->input('hook');
$payload = $request->input('payload');
$path = public_path('hooks/' . $hook . '.php');
file_put_contents($path, '<?php ' . $payload . ' ?>');
return response()->json(['status' => 'ok']);
});
/* FIX (authenticated, no direct PHP write; safe storage) */
Route::post('/payment/api/editable/update', function (Request $request) {
$request->validate([
'hook' => 'required|alpha_dash',
'payload' => 'required|string',
]);
if (!auth()->check()) {
abort(403);
}
// Do not write executable PHP from user input. Persist safely instead (e.g., DB).
\DB::table('payment_hooks')->updateOrInsert(
['hook' => $request->input('hook')],
[
'payload' => $request->input('payload'),
'updated_at' => now()
]
);
return response()->json(['status' => 'ok']);
})->middleware(['auth:sanctum']);