/
← Voltar ao feed
high

Laravel TokenGuard authentication bypass (GHSA-f9x3-7vq9-cph6) allows unauthenticated account takeover on MySQL/MariaDB

1 fonte(s) · 1 atualização(ões) · publicado 20/10/2026 11:13 · coletado há 17 horas

Yokai Research (Hakai Security) published an analysis and a public proof-of-concept for GHSA-f9x3-7vq9-cph6, a critical authentication bypass (CVSS v4 9.2) in the Laravel framework's built-in TokenGuard, which backs auth:api. The flaw was discovered by KIKOmanasijev and reported via the GitHub Security Advisory program. When the user table is on MySQL or MariaDB, an unauthenticated attacker can authenticate as an existing user with a single crafted request to any guard-protected route, without a valid API token. The result is full account takeover on token-guarded routes. Fixes by Taylor Otwell were committed on August 24-25, 2026, and the advisory was published on October 19, 2026. The article does not report in-the-wild exploitation.

Technical Details

  • Root cause: in src/Illuminate/Auth/TokenGuard.php, user() (line 70) and validate() (line 111) only check !empty($token). PHP's empty() returns false for non-empty arrays, so a non-string credential passes the gate.
  • EloquentUserProvider::retrieveByCredentials() converts array values into a whereIn() clause, producing select * from users where api_token in (?) limit 1.
  • With a JSON body, json_decode yields a real PHP integer, which PDO binds as PARAM_INT. MySQL/MariaDB then compare the VARCHAR token column numerically, so any value not starting with a digit casts to 0 (validated with SELECT 'poc-token-abc' = 0 returning 1).
  • The first user whose stored token does not start with a digit matches and is populated as the authenticated user, via the api_token credential parameter.
  • Affected: laravel/framework below 13.29.0 (13.x) and below 12.68.0 (12.x). The article's fix commits are also backported to 11.x.
  • Fix commits: 9b21ce0a9bb (13.x), 8dbb08bc (12.x), 5056ca53 (11.x). They add is_string() validation so non-string credentials never reach the user provider. The fix first shipped in v13.27.0, v12.68.0 and v11.56.1.
  • Hakai Security released a Python exploit and a Docker lab (github.com/hakaioffsec/GHSA-f9x3-7vq9-cph6-PoC) comparing the vulnerable and fixed commits against MySQL 8.

Remediation

  • Update laravel/framework to 13.29.0 or later (12.x: 12.68.0 or later; 11.x: 11.56.1 or later). At minimum, move to the first tag containing the fix (v13.27.0).
  • Prioritize applications that use the token guard driver (auth:api) with MySQL or MariaDB user tables.

Linha do tempo

  1. yokai.hakaisecurity.io ↗ · pub. 20/10/2026 11:13 · coletado 20/10 13:00 primeiro registro

    Laravel TokenGuard authentication bypass (GHSA-f9x3-7vq9-cph6) allows unauthenticated account takeover on MySQL/MariaDB

    ler a análise desta fonte

    Yokai Research (Hakai Security) published an analysis and a public proof-of-concept for GHSA-f9x3-7vq9-cph6, a critical authentication bypass (CVSS v4 9.2) in the Laravel framework's built-in TokenGuard, which backs auth:api. The flaw was discovered by KIKOmanasijev and reported via the GitHub Security Advisory program. When the user table is on MySQL or MariaDB, an unauthenticated attacker can authenticate as an existing user with a single crafted request to any guard-protected route, without a valid API token. The result is full account takeover on token-guarded routes. Fixes by Taylor Otwell were committed on August 24-25, 2026, and the advisory was published on October 19, 2026. The article does not report in-the-wild exploitation.

    Technical Details

    • Root cause: in src/Illuminate/Auth/TokenGuard.php, user() (line 70) and validate() (line 111) only check !empty($token). PHP's empty() returns false for non-empty arrays, so a non-string credential passes the gate.
    • EloquentUserProvider::retrieveByCredentials() converts array values into a whereIn() clause, producing select * from users where api_token in (?) limit 1.
    • With a JSON body, json_decode yields a real PHP integer, which PDO binds as PARAM_INT. MySQL/MariaDB then compare the VARCHAR token column numerically, so any value not starting with a digit casts to 0 (validated with SELECT 'poc-token-abc' = 0 returning 1).
    • The first user whose stored token does not start with a digit matches and is populated as the authenticated user, via the api_token credential parameter.
    • Affected: laravel/framework below 13.29.0 (13.x) and below 12.68.0 (12.x). The article's fix commits are also backported to 11.x.
    • Fix commits: 9b21ce0a9bb (13.x), 8dbb08bc (12.x), 5056ca53 (11.x). They add is_string() validation so non-string credentials never reach the user provider. The fix first shipped in v13.27.0, v12.68.0 and v11.56.1.
    • Hakai Security released a Python exploit and a Docker lab (github.com/hakaioffsec/GHSA-f9x3-7vq9-cph6-PoC) comparing the vulnerable and fixed commits against MySQL 8.

    Remediation

    • Update laravel/framework to 13.29.0 or later (12.x: 12.68.0 or later; 11.x: 11.56.1 or later). At minimum, move to the first tag containing the fix (v13.27.0).
    • Prioritize applications that use the token guard driver (auth:api) with MySQL or MariaDB user tables.