
Reviewed October 25, 2026. CVE-2026-114509 is a Laravel authentication bypass involving the built-in TokenGuard, not a claim that every Laravel login is vulnerable. The Laravel security advisory describes non-string credentials reaching an authentication lookup under certain MySQL or MariaDB configurations. An affected route can identify an unintended existing user without that user’s valid token. The immediate job is to identify the guard actually protecting your API, deploy the corrected framework, and verify both rejection and legitimate access.
A package update and a successful denial are different pieces of evidence. The update identifies the code you intended to deploy. A regression test establishes what a particular request path does. Neither alone establishes whether an account was accessed before remediation. Keep those conclusions separate when closing the issue.
Fixed versions and the scope of this Laravel CVE
Les GitHub-reviewed record identifies Laravel 12.68.0 and 13.29.0 as the fixed releases. It lists the 13.x affected range as 13.0.0 through versions below 13.29.0, and an affected range below 12.68.0. Use a supported corrected release for your application’s branch; these boundaries are not a reason to downgrade a newer fixed build.
| Observed branch | Original fixed boundary | What to establish |
|---|---|---|
| 12.x | 12.68.0 | The serving application uses this or a later corrected release. |
| 13.x | 13.29.0 | The serving application uses this or a later corrected release. |
| An older or customized branch | No separate older-branch fix is specified in the reviewed record | Obtain a supported upgrade or documented maintainer fix; do not assume a major-version number proves safety. |
Treat the version result as inventory, then connect it to deployment and authentication. A vulnerable dependency in an unused development checkout is different from one serving a protected customer API. Conversely, a corrected lockfile on a laptop does not establish that every production instance has been replaced.
Identify TokenGuard before testing a route
Laravel’s authentication documentation distinguishes guards, which authenticate requests, from providers, which retrieve users. It places authentication configuration in config/auth.php. Roles and permissions answer another question: what an authenticated identity may do. That distinction matters here because a route can enforce its permissions correctly while receiving the wrong authenticated identity.
Review the deployed configuration, the middleware on the route, and any custom guard registration together. Do not infer the guard from an endpoint’s name, an Authorization header, or the fact that the application calls itself an API. An application can use several authentication mechanisms across different routes. A finding about the built-in TokenGuard should not be generalized to every session, Sanctum, Passport, or custom implementation without tracing the actual path.
For each relevant route, record the guard, provider, database engine, credential source, and the service responsible for deployment. Avoid copying actual tokens into the inventory. If a team cannot identify the provider or effective configuration, mark the exposure unresolved and assign someone who can inspect the running release. “Uses Laravel” is too broad for either an exposure claim or an exception.
The advisory limits the database condition to certain MySQL or MariaDB configurations. It does not provide a universal configuration fingerprint in its description. Do not fill that gap with an invented SQL mode, collation, token format, or deployment-wide exploitability claim. Updating supported affected dependencies is more defensible than trying to prove a production exception with an unfamiliar public exploit.
How the patch stops the unsafe lookup
Les upstream fix-token-retrieval commit changes two TokenGuard entry points. In user(), the credential must be a string as well as nonempty before the provider lookup. In validate(), a missing or non-string value is rejected before lookup. The added tests require that the provider is not called for a non-string token.
# Reduced explanation of the upstream conditions, not a replacement patch:
user(): string token AND nonempty token -> provider lookup
validate(): missing, non-string, or empty token -> reject
# A string passing this gate must still authenticate successfully.
The important boundary is the call into the user provider. Rejecting an unexpected type before that call prevents it from acquiring a database-dependent meaning during credential matching. This is stronger evidence about the fix than observing an HTTP error after the application has already resolved an identity. It also explains why merely checking for the presence of a credential is not the same as checking its type.
Read the positive and negative paths together. A type gate is not token verification by itself: an arbitrary string must not become an authenticated user just because it passes the gate. Equally, a patch that rejects every credential would make the negative cases pass while breaking the service. Both properties belong in a useful regression test.

Inventory the deployed package without exposing credentials
Run administrative inspection only in an environment you own or are authorized to maintain. The following commands are examples, not results from a customer installation. Composer’s show command can display installed package information; comparing the installed and locked views helps expose an incomplete deployment.
composer show laravel/framework
composer show --locked laravel/framework
composer audit --locked
A clean advisory audit is useful evidence about its data source and package inventory, not proof that every reachable authentication path is safe. Advisory databases and installed artifacts can change at different times. Retain the command’s timestamp, package version, release identifier, and exit result so the evidence can be associated with a particular build.
For immutable images, inspect the image actually serving requests and record its digest. For a release-directory deployment, identify the active release rather than a staging directory with a newer vendor tree. Repeat this check across replicas, regions, and long-running application processes according to your deployment design. A single corrected instance cannot establish fleet-wide remediation.
Resolve the dependency change in a controlled build and run the application’s tests before deployment. Composer installs the versions recorded in an existing lockfile; running an ordinary install from an unchanged vulnerable lockfile is not an upgrade. Review the resulting lockfile and dependency changes, then deploy the tested artifact through the normal release process. Avoid editing vendor files in place and losing the ability to reproduce or audit the fix.
An offline type-gate model you can inspect
We executed the following Python model on October 25, 2026. It checks ten synthetic inputs without a network connection, PHP runtime, Laravel installation, or database. Its only purpose is to make the pre-lookup type boundary observable. It is not a CVE reproduction, a database coercion model, or proof that any installed application is patched. The special empty-string cases approximate the relevant PHP nonempty condition for this example.
"""Offline type-gate model; not Laravel or database exploitation."""
SENTINEL = object()
def model(value=SENTINEL):
calls = []
if not isinstance(value, str) or value in ('', '0'):
return None, calls
calls.append(value)
return ('fixture-user' if value == 'lab-token' else None), calls
cases = [
('missing', SENTINEL, None, 0), ('null', None, None, 0),
('boolean', True, None, 0), ('integer', 7, None, 0),
('array', [7], None, 0), ('object', {'x': 7}, None, 0),
('empty', '', None, 0), ('zero string', '0', None, 0),
('wrong string', 'invalid-lab-token', None, 1),
('valid string', 'lab-token', 'fixture-user', 1),
]
for label, value, expected_user, expected_calls in cases:
user, calls = model(value)
assert user == expected_user and len(calls) == expected_calls
print(f'{label}: user={user!r}, lookup_calls={len(calls)}')
print('PASS: 10 synthetic cases; no network, PHP, Laravel, or database used')
All ten cases passed locally. The missing, null, boolean, integer, array, object, empty-string, and zero-string cases made zero lookup calls. An invalid nonempty string reached the synthetic lookup but returned no user. The fixture token reached the lookup and returned its fixture identity. These results establish behavior of this small model only; the corresponding Laravel and application-level tests still need to run against the deployment under review.
Build a regression result that means more than “401”
Use isolated test accounts and a harmless endpoint that exposes only a synthetic identity marker. The important observation is which identity the server resolved and whether the protected operation ran. A redirect, reverse-proxy denial, validation error, and authentication rejection are different outcomes. An outer layer can stop one request shape while leaving another path into the guard untested.
| Cas | Expected observation | Evidence to retain |
|---|---|---|
| Missing or non-string credential | No authenticated identity; no protected operation; provider not invoked in a focused guard test | Guard-level assertion and sanitized request shape. |
| Invalid nonempty string | No authenticated identity even though a normal credential lookup may occur | Identity assertion and denied operation. |
| Valid fixture token | The intended fixture user can perform its permitted operation | Expected identity and positive-control result. |
| Two fixture users | Each valid token resolves its own user; unrelated resources remain denied | Identity mapping and application authorization assertions. |
| Deployment disagreement | Different replicas or release paths produce inconsistent behavior | Instance or release identifiers; reopen remediation rather than averaging results. |
Add the focused guard test to the framework or application test suite using the interfaces your project already supports. At that layer, a mocked provider can establish whether a malformed value was rejected before user retrieval. At the HTTP layer, inspect the resolved synthetic identity and side effects rather than only the status code. The two tests answer different questions and together make a stronger regression record.
If you also test the database-dependent behavior, use a disposable database with synthetic users and the relevant approved configuration. Document the driver and server versions and keep real credentials out of request captures. Do not publish a working production request as the proof. A useful report can describe the type mismatch, affected path, observed identity, and corrected behavior without distributing a reusable account-takeover recipe.

Investigate earlier access separately from patching
An authentication bypass can affect subsequent activity under the identity the application selected. As a defensive investigation, review identity changes, privileged actions, token-management operations, account recovery changes, and unusual API access within the relevant exposure window. Correlate these with deployment history and application telemetry. These are investigation leads, not a claim that a particular attack or compromise occurred.
Do not start logging complete tokens to create evidence you did not retain previously. Prefer existing sanitized identity records, request identifiers, credential-type metadata where available, and protected server-side audit trails. A log format that records only a status code may not establish which user was resolved. Make that limitation explicit rather than converting missing evidence into a clean bill of health.
Where unauthorized access is substantiated, give containment and credential recovery their own plan. Replacing the framework does not reverse an earlier data read, undo an account change, or revoke a credential an attacker already obtained. Coordinate revocation, account review, evidence preservation, and service restoration according to the observed scope. Avoid blanket claims that every account requires the same response simply because the application uses Laravel.
Use automated testing to verify application behavior, not to certify a CVE
For a follow-up assessment, Penligent’s AI pentesting workflow is one option to evaluate against an owned test environment with dedicated identities and inspectable evidence. Do not assume a dedicated CVE-2026-114509 detector or a completed TokenGuard regression test. Agree the request path, expected identity, allowed effects, and evidence requirements before running any product. The upstream patch and the application’s own regression tests remain the basis for this remediation decision.
Questions that change the remediation decision
Does upgrading PHP alone fix this Laravel CVE?
No. Verify the framework package and authentication path. PHP runtime maintenance is a separate requirement; do not confuse this TokenGuard fix with PHP2Shell.
Does a valid session login prove the API is safe?
No. Trace the guard on the affected route. A different login mechanism can continue to work without exercising TokenGuard.
Should a scanner result override the deployed version?
No single result resolves the whole question. Reconcile the release artifact, effective guard, and focused regression observations. An unexplained disagreement remains open.
Does “patched” prove nobody accessed an account earlier?
No. It establishes a code state when verified in the serving deployment. Historical access needs its own evidence and investigation.
Can the offline example validate a real Laravel installation?
No. It exercises only a synthetic type-gate model. Run the appropriate framework and application tests in an authorized isolated environment.
Close the remediation record when you can identify the corrected serving build, show that malformed credentials cannot resolve a user through the tested path, and preserve a working valid-token control. Keep the historical investigation open for any evidence gaps or suspicious activity that the update itself cannot resolve.

