Safeguard
Supply Chain Security•

Laravel TokenGuard Auth Bypass (CVE-2026-114509): What to Patch

CVE-2026-114509 lets a non-string token log in as another user via Laravel's token guard on MySQL. Update laravel/framework to 12.68.0 or 13.29.0.

Safeguard Security Team
33 min read

GHSA-f9x3-7vq9-cph6 (CVE-2026-114509) is a critical flaw in Laravel's built-in TokenGuard: on MySQL or MariaDB, a non-string API token could authenticate a request as an existing user without that user's token. It affects laravel/framework below 12.68.0 and 13.x below 13.29.0. Update now, then confirm the version in every lockfile and image.

The fix itself is not new. Laravel tagged the patched releases on 25 August 2026, and the advisory explaining why they mattered was published on 19 October 2026, about eight weeks later. The CVE record followed on 21 October. If your team updates Laravel on a regular cadence, you are probably already covered. If you pin framework versions, run older application skeletons that still define a token guard, or maintain Laravel 10 or earlier, this post is for you.

What happened

Date and time (UTC, 2026)EventSource
25 Aug, 01:15:02Fix commit 9b21ce0a9bb2b2599978bc0b0df4abea952ad31c, "fix token retrieval", lands on the 13.x branch, authored by Taylor Otwell (commit timestamp 24 Aug 20:15:02 at UTC minus 5).GitHub commit patch
25 Aug, 01:16:16The same change lands on 12.x as commit 8dbb08bccac1be095dba4a9d259a419620f1e8a5.GitHub commit patch
25 Aug, 14:16:00v13.27.0 published on Packagist. Its tagged TokenGuard.php already contains the new type check (our reading of the source).Packagist metadata, tagged source
25 Aug, 14:18:36v12.68.0 published on Packagist (reference 1343c22b92edd48e29ff273d8ce7c15cf75d974c); GitHub release created 14:19:59. Release notes list one item, "Fix resource loading" (#61323), and do not mention security.Packagist metadata, GitHub release
25 Aug, 14:29:04v11.56.1 published on Packagist. Its tagged TokenGuard.php also contains the type check (our reading; the advisory does not list any 11.x fix).Packagist metadata, tagged source
25 Aug, 20:54:30v13.28.0 published (reference cb89165a4849847f03c2bca92bb52c749bf83978).Packagist metadata
25 Aug, 20:57:16v13.29.0 published (reference 6e2c363716964d8238cee7097b258119a984f0cf); GitHub release created 20:58:51 with no notes beyond the version bump.Packagist metadata, GitHub release
19 OctGitHub security advisory GHSA-f9x3-7vq9-cph6, "Token-based API guard Auth Bypass", published on the laravel/framework repository, severity Critical, CVSS 4.0 score 9.2. A reporter is credited under the GitHub handle KIKOmanasijev.GHSA
20 Oct, 10:45:58v13.38.0 published, the newest 13.x release at the time of writing.Packagist metadata
21 Oct, 21:49:29CVE-2026-114509 published to the CVE list by GitHub as CNA (time from the OSV record generated from the CVE list).OSV
21 Oct, 22:16:49NVD publishes CVE-2026-114509 with status "Awaiting Analysis".NVD API
22 Oct, 17:29:28NVD record last modified; still awaiting NVD's own analysis.NVD API
23 OctPackagist's security advisory API returns 28 advisories for laravel/framework, none of them this one. GitHub's global advisory page for the GHSA ID returns 404.Packagist API, GitHub

The advisory page shows a date (19 October) but no time, so we have left the time blank rather than guess.

What the public record says

The GHSA is the primary source, and it is short. It says Laravel's built-in TokenGuard, when configured as a standard token-based API guard, can be bypassed so that a request authenticates as an arbitrary existing user without that user's API token. The condition is a database configuration of MySQL or MariaDB and a "specially crafted, non-string credential value" that is mishandled during the lookup. The impact statement is account takeover on any route protected by the affected guard, by an unauthenticated attacker.

The CVE description, written by GitHub as the CNA and repeated in NVD and OSV, adds two small details. It frames the root cause as TokenGuard not rejecting a non-string credential, and it states the affected ranges precisely: everything below 12.68.0, and 13.0.0 up to but not including 13.29.0. It classifies the weakness as CWE-287 (improper authentication) and CWE-1287 (improper validation of specified type of input).

The fix commits are the most precise source of all. Each one changes two lines in src/Illuminate/Auth/TokenGuard.php and adds two tests to tests/Auth/AuthTokenGuardTest.php. Both new tests assert the same thing: when the token is not a string, the guard must never call the user provider at all.

No source we read reports exploitation in the wild. No public proof of concept is linked from the advisory, NVD or OSV. The advisory does not list indicators of compromise.

Where sources differ

There are four gaps worth knowing about, none of which changes what you should do.

  1. The first fixed 13.x version. The advisory and the CVE both name 13.29.0. Our reading of the tagged source shows the same type check already present in v13.27.0 (published 14:16 UTC on 25 August) and v13.28.0 (published 20:54 UTC the same day). The advisory is the authority here, and it is the conservative choice, so treat 13.29.0 as the floor. In practice you should be on a much newer 13.x release anyway.
  2. Laravel 11. The advisory's ranges imply that every version below 12.68.0 is affected, which includes all of 11.x. Yet v11.56.1, published on 25 August, and v11.57.0, published on 29 September, both contain the type check in their tagged TokenGuard.php. Laravel's own support table says security fixes for Laravel 11 ended on 12 March 2026, which may be why the advisory does not list an 11.x fix. If you are on 11.x, our reading is that 11.56.1 or later has the change, but no official source confirms that, so plan your move to 12 or 13.
  3. Laravel 10 and earlier. The newest 10.x release, v10.50.3 from 12 August, predates the fix and does not contain it. Laravel 10 left security support on 4 February 2025. There is no fixed 10.x release.
  4. Database feeds. The CVE is in NVD and OSV, and OSV links the four fix and release references. But OSV returns "not found" for the GHSA ID itself, GitHub's global advisory database page for it returns 404, and Packagist's advisory API (the default source for composer audit) has no entry yet. Tools that rely on those feeds may stay silent for a while. Check versions directly rather than waiting for an audit tool to flag it.

Technical details

Identifiers and scores

FieldValueSource
GHSA IDGHSA-f9x3-7vq9-cph6GHSA
CVE IDCVE-2026-114509GHSA, NVD, OSV
TitleToken-based API guard Auth BypassGHSA
OSV summaryLaravel TokenGuard authentication bypass through non-string API credentialsOSV
Packagelaravel/framework (Composer)GHSA
SeverityCriticalGHSA, NVD
CVSS 4.0 base score9.2GHSA; NVD lists the same as a secondary score from the CNA
CVSS 4.0 vectorCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:NGHSA, NVD
WeaknessesCWE-287, CWE-1287NVD, OSV (the GHSA page itself shows "No CWEs")
NVD statusAwaiting Analysis, no NVD primary score yetNVD API, fetched 23 Oct
CNAGitHub (security-advisories@github.com, GitHub_M)NVD, OSV
Reporter creditKIKOmanasijevGHSA

Reading the vector in plain words: reachable over the network, low attack complexity, no privileges and no user interaction needed, high impact on confidentiality, integrity and availability of the vulnerable system. The one qualifier is AT:P, "attack requirements present", which reflects that the application must use the token guard and run on MySQL or MariaDB.

Affected and fixed versions

Release lineAffected (per advisory and CVE)First fixed (per advisory)Notes from tagged sourceLaravel support status
13.x>= 13.0.0, < 13.29.013.29.0 (25 Aug, 20:57 UTC)Check present in 13.27.0 and 13.28.0 tags tooSecurity fixes until 17 March 2028
12.x< 12.68.012.68.0 (25 Aug, 14:18 UTC)12.67.0 lacks the check; 12.68.0 has itSecurity fixes until 24 February 2027
11.xCovered by < 12.68.0None listed11.56.1 and 11.57.0 contain the check; 11.56.0 does notSecurity support ended 12 March 2026
10.x and olderCovered by < 12.68.0None10.50.3 (12 Aug) lacks the checkSecurity support ended 4 February 2025

Newest releases at the time of writing, from Packagist: 13.38.0 (20 October), 12.69.3 (29 September), 11.57.0 (29 September), 10.50.3 (12 August).

Fix commits

BranchCommitAuthor dateFiles changed
13.x9b21ce0a9bb2b2599978bc0b0df4abea952ad31cMon, 24 Aug 2026 20:15:02 -0500src/Illuminate/Auth/TokenGuard.php (2 lines), tests/Auth/AuthTokenGuardTest.php (22 lines added)
12.x8dbb08bccac1be095dba4a9d259a419620f1e8a5Mon, 24 Aug 2026 20:16:16 -0500Same two files, same line counts

Both commits carry the subject line "fix token retrieval". The change to the guard is two conditions:

// TokenGuard::user(), before
if (! empty($token)) {

// TokenGuard::user(), after
if (is_string($token) && ! empty($token)) {
// TokenGuard::validate(), before
if (empty($credentials[$this->inputKey])) {

// TokenGuard::validate(), after
if (! is_string($credentials[$this->inputKey] ?? null) || empty($credentials[$this->inputKey])) {

That is the entire production change. Everything else in the commits is test coverage that checks the user provider is never consulted when the token is not a string.

Release references on Packagist

These are the source commit references Packagist records for each relevant tag, useful if you install from a mirror or verify a vendored copy.

VersionPublished (UTC)Source reference
v13.26.02026-08-18 12:30:1017f6e626e014dd9b4a380ae2924b590a129a5307
v13.27.02026-08-25 14:16:00f3fa8f3591fa2e8f0b7dedfffc3fc324d2aad31b
v13.28.02026-08-25 20:54:30cb89165a4849847f03c2bca92bb52c749bf83978
v13.29.02026-08-25 20:57:166e2c363716964d8238cee7097b258119a984f0cf
v12.67.02026-08-18 13:37:47fe2cdaba052cbb9f350761ccefc7ac221cbdf0b5
v12.68.02026-08-25 14:18:361343c22b92edd48e29ff273d8ce7c15cf75d974c
v11.56.02026-08-20 12:38:313dc23992442f06ceaabe9b9b18e054d116a7bd2a
v11.56.12026-08-25 14:29:04d5a6525f18dc8374167c9faa890715bed7e29283
v13.38.02026-10-20 10:45:58c42f9abd4a3d2f9a3cd6be109255ddce8092ceb8
v12.69.32026-09-29 12:53:2558ea544a2a80dc03c168e13a5dc9a1d176a88717

The reference field in your composer.lock entry for laravel/framework should match the row for your version.

The class of bug, conceptually

This is a type confusion bug at the boundary between an HTTP request, a PHP framework and a SQL database. Three ordinary behaviours line up.

First, the token guard reads the token from several places in order: the query string, the request input (which includes form fields and JSON bodies), the Authorization: Bearer header, and the HTTP basic auth password. The header and password sources always produce strings. The query string and request input do not have to: PHP's request parsing and JSON decoding can both hand the framework a value that is not a string.

Second, the guard passes whatever it found to the user provider's retrieveByCredentials method. Both built-in providers, EloquentUserProvider and DatabaseUserProvider, build a query from the credentials array. Their code treats a list differently from a scalar: a list becomes a "where in" condition and a scalar becomes a plain equality. Neither provider checks that a token is a string, because until this fix, the guard was expected to have done that.

Third, MySQL and MariaDB compare values of different types by converting them. MySQL's reference manual says that when a string is compared with a number, both are compared as floating point numbers, and it notes that many different strings can convert to the same number, which is why an index on a string column cannot be used for such a lookup. MariaDB documents the same family of implicit conversion rules and recommends explicit CAST instead of relying on them. A random token stored as text can therefore compare equal to a value that is nothing like it.

Put together, a value that was never a valid token can reach the database as something other than a string, and the database can decide that it matches somebody's stored token. The query returns the first matching row, and the guard treats that row as the authenticated user. That is why the advisory talks about "an unintended user record" rather than a specific victim: the attacker does not choose who they become in the general case, but any existing account, including an administrator, could be the match.

The fix closes the first link in the chain. If the token is not a string, the guard stops and returns no user. It does not change the providers or the database, which is the right scope for a patch release but worth remembering if you have written your own guard or provider that follows the same pattern.

Two observations from reading the code, which the advisory does not state and which you should not rely on in place of patching:

  • PostgreSQL and SQLite are not named by the advisory. Their comparison rules differ from MySQL's, which is presumably why the advisory limits the scope, but we have not tested them and you should update regardless.
  • When the guard's hash option is true, the token is passed through PHP's hash('sha256', ...) before the lookup, and that function requires a string. The advisory does not distinguish hashed from plain-text tokens. Treat both as affected.

Indicators of compromise

The advisory, NVD and OSV publish no indicators of compromise: no IP addresses, user agents, request signatures or hashes. Any list of indicators you see elsewhere did not come from these primary sources. The detection section below describes what to look for in your own logs instead.

How to check your installed version with Composer

# The version actually installed in vendor/
composer show laravel/framework

# The version pinned in composer.lock, regardless of vendor/
composer show --locked laravel/framework

# The framework's own view
php artisan --version
php artisan about --only=environment

Read the version line and compare it with the table above: 12.68.0 or later on 12.x, 13.29.0 or later on 13.x. If the output shows 11.x or 10.x, see the affected versions table above and the FAQ entry on Laravel 10.

How it works, in plain language

An API token is a long random password that a program sends instead of a person typing one. Laravel's token guard is the simplest way to check those tokens: it takes the token from the request, looks for a user whose api_token column holds the same value, and treats the request as that user if it finds one.

The bug is that "the same value" turned out to be negotiable. The guard checked that the token was not empty, but not that it was text. If the request supplied something other than text, the guard passed it on, the framework built a database query from it, and MySQL, being helpful, converted types to make the comparison work. The comparison could come back true for a user who never sent anything.

The fix makes the guard ask the right question first: is this actually a string? If not, the answer is no user, and the provider is never asked.

Who is affected

You are affected only if all of these are true:

ConditionHow to checkNotes
laravel/framework is below 12.68.0, or 13.x below 13.29.0composer show --locked laravel/frameworkIncludes all 11.x, 10.x and older per the advisory
A guard uses the built-in token driverLook in config/auth.php for 'driver' => 'token'The laravel/laravel 7.x skeleton shipped an api guard with this driver; the 8.x and later skeletons in that repository do not
Routes are protected by that guardLook for auth:api or auth:<guard name> middleware on routesOnly routes behind the token guard are exposed
The user provider reads from MySQL or MariaDBCheck DB_CONNECTION and the provider's connectionThe advisory names MySQL and MariaDB only

You are not affected by this advisory if you authenticate APIs with Laravel Sanctum or Laravel Passport, which use their own guards, or with session cookies only. Laravel's current authentication documentation recommends Sanctum or Passport for API tokens and no longer documents the token driver; the Laravel 5.8 documentation was the last to describe it as a feature, with a note recommending Passport for production applications. That history matters: the apps most likely to still use the token guard are older applications upgraded in place over many years, where config/auth.php was never rewritten.

What to do now

1. Update the framework

On 13.x:

composer require laravel/framework:^13.29 --update-with-dependencies

On 12.x:

composer require laravel/framework:^12.68 --update-with-dependencies

If your composer.json already uses a caret constraint such as ^13.0 or ^12.0, a plain update is enough:

composer update laravel/framework --with-dependencies
composer show --locked laravel/framework

Commit the updated composer.lock, run your test suite, and deploy. Within a major version, Laravel's release policy says minor and patch releases should never contain breaking changes, so moving from 12.67 to 12.69, or from 13.20 to 13.38, should be routine. Run the tests anyway.

2. Confirm the guard's configuration

# Which guards use the token driver?
grep -n "'driver'\s*=>\s*'token'" config/auth.php

# Which routes use the api guard (or another token guard by name)?
grep -rn "auth:api" routes/ app/
php artisan route:list --json | jq '.[] | select(.middleware | tostring | test("auth:api")) | .uri'

If nothing uses the token driver, you are not exposed to this specific bug. Update anyway, and consider removing the unused guard block so it cannot be wired up later by accident.

3. Find every copy across your estate

One repository is easy. Most organisations have Laravel in many places: the main app, admin panels, internal tools, a forgotten marketing microsite, a vendor's product you host. Find the lockfiles and read the version from each:

# Every composer.lock under a directory of checked-out repos
find . -name composer.lock -not -path "*/vendor/*" -print0 |
  while IFS= read -r -d '' f; do
    v=$(jq -r '.packages[] | select(.name=="laravel/framework") | .version' "$f")
    [ -n "$v" ] && printf '%s\t%s\n' "$v" "$f"
  done | sort -V

For container images, read the lockfile out of the image without running the application:

docker run --rm --entrypoint cat your-registry/your-app:tag /var/www/html/composer.lock \
  | jq -r '.packages[] | select(.name=="laravel/framework") | .version'

Adjust the path to wherever your image places the application. If the image ships vendor/ but not composer.lock, Composer's installed metadata is in vendor/composer/installed.json:

docker run --rm --entrypoint cat your-registry/your-app:tag /var/www/html/vendor/composer/installed.json \
  | jq -r '.packages[] | select(.name=="laravel/framework") | .version'

On a running server:

cd /path/to/app && php artisan --version

4. Do not rely on composer audit yet

composer audit checks installed packages against the Packagist advisory API by default. As of 23 October, that API has no entry for this advisory, so an audit run today will not flag it. Use the version checks above. When Packagist adds the advisory, add composer audit --locked to CI so the version cannot drift back:

composer audit --locked --format=summary

5. If you cannot update today, close the input path

If a release freeze or a large version gap blocks the update, a small middleware can reject non-string token values before the guard sees them. This is a stopgap, not a replacement for the patch:

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class RejectNonStringApiToken
{
    public function handle(Request $request, Closure $next, string $key = 'api_token')
    {
        foreach ([$request->query($key), $request->input($key)] as $value) {
            if ($value !== null && ! is_string($value)) {
                abort(401);
            }
        }

        return $next($request);
    }
}

Register it so it runs before auth:api on every route group that uses the token guard. If you customised input_key in the guard's configuration, pass that name instead of api_token.

A cleaner medium term option is to move the API off the token guard to Sanctum, which Laravel's documentation recommends for first-party APIs, SPAs and mobile clients. That is a migration, not a hotfix, so schedule it after you have patched.

6. Look back through your logs

Because the fix shipped on 25 August, your exposure window runs from whenever the app went live on a token guard until you deployed a fixed release. There are no published indicators, so look for what the bug needs:

  • Requests to token guarded routes where the token parameter in the query string or body was not a plain string, for example PHP array syntax in the query string or a non-string JSON value. Most web server and proxy logs record the query string; few record bodies, so absence of evidence here is weak.
  • Successful authenticated responses on API routes that came from clients with no history of holding a token, especially if many different clients resolved to the same user ID.
  • Unusual activity on the accounts that sort first in your users table, since a lookup that returns "the first matching row" tends to land on the same few rows.

If you find signs of misuse, rotate every API token in the table, review actions taken under the affected user IDs, and treat any data those users could reach as exposed.

What would have helped

Nothing about this bug required sophisticated tooling to prevent or to fix. It required knowing where the guard ran, checking types at the edge, and moving to new framework releases promptly. Most of the useful habits are ordinary engineering.

Check types where untrusted input meets authentication

Every authentication lookup that takes a value from a request should first assert the value's type and shape. A token is a string of a known length and alphabet. Reject anything else before it reaches a query builder. Laravel's own documentation shows this habit in its custom guard example: the Auth::viaRequest sample casts the request value to a string before it queries the users table. The token guard simply lacked the same line. If you have written your own guards, providers or "find user by API key" helpers, search them for this pattern today:

grep -rn "retrieveByCredentials\|where('api_token'\|where(\"api_token\"\|->where('token'" app/

For each hit, ask whether the value could be something other than a string by the time it reaches the query. Form request validation with a string rule, a cast, or an explicit is_string check all work.

Prefer strict comparisons in the database layer

MySQL's own manual warns about comparing string columns with numbers. Bind tokens as strings and look up by a unique hashed column of fixed length, and add "what happens if this value is not a string" to your review checklist for authentication code.

Keep framework patch releases flowing

The fixed releases were available eight weeks before the advisory explained them. Teams that took Laravel's weekly releases as they came were protected before anyone outside the project knew there was something to protect against. Teams that pin exact framework versions and update only when an advisory appears were exposed for the whole gap. A dependency update bot or a scheduled job that runs composer update within your constraints, runs the tests and opens a pull request each week closes most of that gap at very low cost.

Know which apps use which authentication driver

An inventory of frameworks and versions is the first half. The second half is configuration: which applications define a token guard, which routes use it, and which database sits behind it. Keeping a short record of each application's authentication setup turns "are we exposed" from a week of archaeology into a query.

Retire unsupported framework lines

Laravel 10 and 11 are past their security support dates. This advisory lists no fix for either. Applications on unsupported lines will keep accumulating advisories like this one, each with no patched release, so an upgrade plan with a date is a security control, not a nice to have.

Where Safeguard fits

Safeguard does not change how Laravel's token guard behaves, and nothing here would have prevented the bug. What it helps with is the operator's problem: knowing which of your applications carry a vulnerable framework version, which of those actually matter, and moving them to the fixed release quickly.

  • Inventory and matching. Safeguard scans repositories, container images and SBOM files (safeguard scan --dir ., safeguard scan --image <name>, safeguard scan --sbom <file>, with JSON results under ./output) and builds a full transitive inventory. Its software composition analysis covers Composer alongside npm, PyPI, Maven and Gradle, Go, Cargo, NuGet and Bundler, plus container layers. Vulnerability matching draws on several databases, including NVD, GHSA and OSV, which matters for an advisory that has reached some feeds and not others. The platform shows which projects contain a given component and version, so "which apps resolve laravel/framework below 12.68.0" becomes a query rather than a grep across every repository.
  • Prioritisation. Reachability analysis helps rank findings by whether your code reaches the vulnerable paths. It cannot read your config/auth.php intent for you, so treat a reachability result as a starting point and confirm the guard configuration with the grep above.
  • Policies and gates. A policy can fail a build that resolves laravel/framework below the fixed version, so an old lockfile on a long lived branch cannot bring it back.
  • Fixes with approval. The Safeguard CLI's assistant can edit composer.json, run composer update and your tests, and ask before each command. Autonomous remediation can open fix pull requests, and ships switched off by default.

Where Safeguard does not help: it cannot tell whether a request in your logs was an attack, it does not rotate your API tokens, and it cannot patch a Laravel application you host for a vendor but do not build. Those remain jobs for your incident process and your vendor.

Zero-Day Discovery and Gold

Safeguard's Zero-Day Discovery looks for previously unknown flaws before a CVE exists, in an agentic mode and a deterministic scanner mode, and issues findings as SGZ advisories before they reach public CVE databases. It covers seven package ecosystems. This vulnerability was reported to Laravel by an outside reporter, credited on the advisory, and fixed by the framework's maintainers.

Gold Open Source at gold.safeguard.sh is free and needs no login; it shows CVSS, EPSS, KEV status, affected and fixed versions and a recommended safe version for a CVE, through the site, a free read API and a CI gate GitHub Action. We have not confirmed that it holds a record for CVE-2026-114509 at the time of writing, so check the site rather than relying on this post. Gold Registry at registry.safeguard.sh provides hardened, signed components held to zero exploitable critical or high CVEs; we make no claim that it carries a laravel/framework build. The habit worth taking from both is the one this incident rewards: pull patched, signed components from a curated source and rebuild fast.

Common mistakes

  • Waiting for composer audit to go red. As of 23 October, the Packagist advisory API has no entry for this advisory. A clean audit does not mean a safe version.
  • Checking composer.json instead of composer.lock. A constraint like ^12.0 says nothing about what is installed. Read the lock or vendor/composer/installed.json.
  • Updating the repository but not the image. If your container image was built in September from a lockfile pinned to 12.67.0, it still runs 12.67.0. Rebuild and redeploy, then check the running image.
  • Assuming Sanctum users are affected. The advisory names the built-in TokenGuard only. Sanctum and Passport have their own guards. You should still update the framework, but you do not need to treat a Sanctum only API as compromised.
  • Assuming you are safe because config/auth.php looks modern. Packages and service providers can register guards too. Run php artisan route:list and check middleware names, not only the config file.
  • Treating the middleware stopgap as the fix. It covers the token parameter you name. The framework patch covers the guard itself. Do both, then remove the stopgap after the update ships.

Open questions

  • Why 13.29.0 and not 13.27.0? The tagged source suggests 13.27.0 and 13.28.0 already contain the check. The advisory has not explained the choice. It may reflect how the fix was merged and tagged on a busy release day.
  • Will an 11.x fix be listed? The 11.x releases from 25 August onward appear to contain the change, but the advisory does not mention 11.x.
  • When will the advisory reach Packagist and GitHub's global database? That determines when composer audit and many dependency bots start flagging it.
  • Will NVD assign its own score? NVD shows only the CNA's CVSS 4.0 score of 9.2 and the status "Awaiting Analysis".

FAQ

Is CVE-2026-114509 being exploited?

None of the sources we read reports exploitation, and the advisory publishes no indicators. The bug is simple to understand once the fix is public, though, and the fix has been public in the source since 25 August. Treat it as urgent if you use the token guard.

Which version do I need?

On 13.x, 13.29.0 or later. On 12.x, 12.68.0 or later. In practice, take the newest release in your line, which was 13.38.0 or 12.69.3 at the time of writing.

I use Laravel Sanctum. Am I affected?

Not by this advisory, which concerns the built-in TokenGuard. Sanctum uses its own guard. Update the framework anyway, since you may have a token guard defined that you have forgotten about.

How do I know if my app uses the token guard?

Look in config/auth.php for a guard with 'driver' => 'token', then look for routes using that guard's middleware, usually auth:api. Applications created from the Laravel 7 skeleton or earlier shipped such a guard by default.

We use PostgreSQL. Do we need to patch?

The advisory names MySQL and MariaDB. We have not tested other engines and the advisory does not say they are safe. Patch regardless; the update is small and the guard change is correct for every database.

Why was the advisory published eight weeks after the fix?

Laravel has not said. A gap between a quiet fix and a public advisory is a common pattern in open source, often to give users time to update before the details are public. It also means teams that update only when an advisory appears were exposed for the whole gap.

Should we rotate all API tokens?

Not because of the bug itself, which does not reveal tokens. Rotate if your logs show signs of misuse, or if you cannot review the window and want certainty. If you rotate, consider moving to hashed storage at the same time.

We are on Laravel 10. What now?

There is no fixed 10.x release, and Laravel 10 has been out of security support since February 2025. Apply the middleware stopgap or patch TokenGuard.php in your own fork with the same two line change, then plan an upgrade to 12 or 13.

Did Safeguard find this vulnerability?

No. It was reported to the Laravel maintainers by an outside reporter, who is credited on the advisory, and fixed by the maintainers.

Fix it without waiting for upstream

For this advisory, upstream already shipped the fix in August, so the first gap that matters is between that release and your production builds. For teams on Laravel 10 or 11, where no supported fix is listed, the second gap applies too.

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would have helped

These are real product sessions on other examples; none of them shows this Laravel incident.

The CLI demo shows the assistant fixing a lodash CVE: it reads the finding and advisory, asks before each command, edits package.json to lodash 4.17.21, runs npm install and npm test with approval, and pushes nothing. For CVE-2026-114509, the same flow applies to a Laravel repository: ask it to move laravel/framework to 12.68.0 or 13.29.0 or later, approve composer update, then approve php artisan test before anything is committed.

Click through it at your own pace, or open it full screen.

The desktop app demo shows a CLI session in the conversation list, a request for work on the computer, a folder choice, and Approve or Deny on each command and file edit, ending with an upgrade done and tests passing. Here you would pick the folder of an older Laravel app, ask it to check config/auth.php for a token guard and bump the framework, and approve each edit and each Composer and test command one by one.

Click through it at your own pace, or open it full screen.

The Claude demo shows connecting Claude to the Safeguard MCP server with OAuth and choosing which tools Claude can use. Once connected, the estate wide question for this advisory, which projects resolve laravel/framework below the fixed versions, is something you can ask in plain language against the projects already scanned in your account.

Click through it at your own pace, or open it full screen.

To try it on your own projects, download Safeguard and read the CLI documentation. For PHP more broadly, see PHP security explained and how to find and patch every PHP runtime after PHP2Shell. For the inventory side of incident response, see finding affected products fast with SBOMs, and for other incidents this month, our October 2026 roundup.

Quick check

Your composer.lock shows laravel/framework 13.28.0, which contains the type check in its source. Are you done?

Not by the advisory's terms. It names 13.29.0 as the first fixed 13.x release, so update to 13.29.0 or later and leave no room for argument in an audit.

composer audit returns no advisories for your Laravel 12.60 app. Is it safe from CVE-2026-114509?

No. As of 23 October the Packagist advisory API, which composer audit uses by default, has no entry for this advisory. Check the version directly and update to 12.68.0 or later.

Sources

Last reviewed: 23 October 2026. This is a developing story; check the linked advisories for the latest status.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.