Contents (6)
Some security bugs are so simple you do not believe they work at first. Laravel’s new TokenGuard vulnerability is one of them: instead of a real token, the attacker sends an array containing zero, and the app logs them in as a real user.
It is tracked as CVE-2026-114509 with a score of 9.2. The fixed Laravel versions shipped quietly at the end of August, but the public details only came out on 19 October. Now that everyone knows where the bug is, projects that have not updated are exposed.
Who is affected
Not every Laravel project is affected. Yours is at risk if all three of these are true:
- **
config/auth.phphas a guard with'driver' => 'token'.** That is the old, simple guard that keeps the token in a column of the users table. - The database is MySQL or MariaDB.
- Laravel is below 12.68.0 or 13.29.0.
Sanctum and Passport are not affected. But do not underestimate one detail: up to Laravel 7, the api guard in new project skeletons used exactly this token driver. Projects upgraded several times since then may still carry that setting, even if nobody remembers it.
Where the bug was
Before the fix, TokenGuard only checked that the token was not “empty”. In PHP, a one-element array such as [0] is not empty as far as empty() is concerned. When an attacker sends a JSON body with an array, it passes the check and reaches the database layer.

For array input, Eloquent uses whereIn(), so the query becomes something like api_token in (0). This is where MySQL comes in: when a string is compared with a number, MySQL converts the string to a number. A string that starts with a letter becomes zero, and zero equals zero. The query returns the first user whose token starts with a letter, and the guard treats them as authenticated.
The attacker’s request is nothing more than this:
POST /api/orders HTTP/1.1
Content-Type: application/json
{"api_token": [0]}
The fix
Laravel’s fix comes down to one line: before touching the database, check with is_string() that the token really is a string. If it is not, the request is rejected right there.
// The idea behind the fix, in short.
if ( ! is_string( $token ) || $token === '' ) {
return null;
}
What to do now
- Update Laravel. Run
composer update laravel/frameworkto reach 12.68.0, 13.29.0 or later. Version 11.56.1 contains the same check, although the advisory does not list it. - **Check
config/auth.php.** If any guard uses'driver' => 'token', that project is a priority, especially on MySQL or MariaDB. - If you are on Laravel 9 or 10, reports say those branches still had the old check as of 21 October. Upgrade to a supported version or move the guard to Sanctum.
- **Add
composer auditto your workflow.** It lists known vulnerabilities in your dependencies, and it belongs in CI, not only in a crisis.
A lesson that is not only Laravel’s
This bug is a good reminder that “user input is always a string” is a false assumption. Anything from JSON or a form can be an array, a number or null. When that input reaches a database that silently converts between types, the result can be a full authentication bypass.
The simple rule: check the input’s type explicitly, up front. In Laravel, the string validation rule does exactly that. In WordPress, when you register a REST route, give every argument 'type' => 'string'. It is one line of code, and it stops a whole class of bugs.
Sources
$ ./request_review
Facing the same problem in your own store?
Senior WordPress and WooCommerce backend engineering for complex production problems.
Request a Technical Assessment
## Comments