Skip to main content

Laravel TokenGuard: CVE-2026-114509

Bypass Laravel's TokenGuard with a non-string token (CVE-2026-114509), then detect and patch it.

Task 1: Introduction: A Token That Isn't a String

Task 2: How an Array Becomes a Match

Task 3: Fingerprint the Vulnerable API

Task 4: Hijack an Account Without Its Token

Task 5: Verify the Fix and Detect the Bypass

Task 6: Conclusion: Closing the Type Gap

Back to all walkthroughs
Room Icon

Laravel TokenGuard: CVE-2026-114509

Max room.

Bypass Laravel's TokenGuard with a non-string token (CVE-2026-114509), then detect and patch it.

easy

45 min

14

User profile photo.
User profile photo.
User profile photo.

To access material, start machines and answer questions login.

On the morning of October 19, 2026, Lena Hartwell opened a security advisory and stopped partway down the page. Lena heads the two-person backend team at Kettlebrook (a class booking platform for independent fitness studios). Its mobile app talks to a Laravel-powered Application Programming Interface () that identifies every member by an API token. The advisory said the token system she'd selected years ago could be exploited to let an unauthenticated request take over a member's account. Framework upgrades at Kettlebrook are all held up until a quiet week, and quiet weeks are the exception. She wanted one answer by the end of the day: Is production exposed, and if so, what do we do?

The Advisory

The advisory describes -2026-114509, the Common Vulnerabilities and Exposures identifier for this flaw, also tracked in GitHub's security advisory. The weak point is Laravel's built-in token guard, the part of the framework that reads an API token off a request and looks up the member it belongs to. The guard doesn't require the credential to be a string. Under certain MySQL or MariaDB database configurations, a crafted non-string credential can match a real member's stored token. An attacker with no token can then authenticate as that member on any route the guard protects. The advisory scores it 9.2 on the Common Vulnerability Scoring System () version 4.0 scale, which lands it in the Critical band.

The rating comes with a caveat around reach. The vulnerable guard uses the token driver with unhashed tokens, and the bypass works on affected MySQL or MariaDB configurations. A current Laravel app skeleton doesn't define that guard by default; a developer would add it. At the time of writing, the vulnerability isn't on the Cybersecurity and Infrastructure Security Agency (CISA) Known Exploited Vulnerabilities (KEV) list. There's no public reporting from that time of it being exploited in the wild. A proof-of-concept from Hakai Security (hakaioffsec) did follow the advisory.

Your Engagement

Lena has brought you in to answer her question from the outside (i.e., the way an attacker would first see it). You'll be working from the AttackBox and will be reaching Kettlebrook's production API over HTTP using curl. You get absolutely no shell on the target and no SSH access at all, just what the network is going to show you.

We'll nail the bug, fingerprint the API, and take over an account without its token. Then we'll switch to the defender's chair and see what the attack leaves behind and how we can close the gap. The credential we're using to take over the account isn't a password, and it's not even a string. It's a number in square brackets. How can [0] match a real member's token, which is going to be a long random string that looks absolutely nothing like it? That's where we start.

Learning Objectives

This room takes you through one real-world vulnerability, from the moment Lena spots the advisory to the change that closes it. You'll learn how to:

  • Explain how an integer array reaches the lookup
  • Predict which tokens MySQL matches to an integer
  • Fingerprint a Laravel API's version and guard
  • Diagnose why a query-string array fails
  • Take over an account without its token
  • Identify what a default access log misses
  • Identify the fix's type check and release

Room Prerequisites

This room assumes you're comfortable sending HTTP requests with curl from a Linux terminal and reading the JSON responses that come back. It also assumes you have a basic grasp of what an API token is and what a SQL WHERE clause does. You won't need any or Laravel knowledge, as we'll cover the framework as we go. If your /web fundamentals are a bit weak, then the Junior Penetration Tester path will cover that.

Before you start Task 2, press the Start AttackBox button to start the Attacker machine and press the Start Machine button to start the Target machine so that they are ready when you need them in later tasks.

Set up your virtual environment

To successfully complete this room, you'll need to set up your virtual environment. This involves starting both your AttackBox (if you're not using your VPN) and Lab Machines, ensuring you're equipped with the necessary tools and access to tackle the challenges ahead.
Attacker machine
Status:Off
Lab machine
Status:Off