Laravel MongoDB 5.11: what I would change after CVE-2026-88022

Laravel MongoDB 5.11: what I would change after CVE-2026-88022

mongodb/laravel-mongodb 5.11.0 tagged 10 Sep 2026 for CVE-2026-88022. A 3-arg where('=', $array) is now a literal $eq. I would run composer show and composer audit --locked before I claim I am patched. This is not a Laravel core CVE.

· 8 min read #php #security #laravel #mongodb #composer

 CVE-2026-88022 is a mongodb/laravel-mongodb package bump, not Laravel core

Caption: composer show first. If the package is missing, stop. The lock bump is 5.11.0. Illuminate does not ship this CVE.

I did not dump a Mongo collection tonight. I opened a throwaway Laravel 13 tree on the VPS and ran composer show. mongodb/laravel-mongodb 5.11.0 tagged 10 September 2026. Packagist’s time on that version is 2026-09-10T12:22:19+00:00. The GitHub release stamp is 12:33:03Z the same day. GHSA-68xx-ccm2-m445 published 11 Sep 2026. NVD published CVE-2026-88022 on 10 Sep 2026. This is a Composer package CVE. It is not laravel/framework.

The failure this week is famous for two shapes. Either composer show mongodb/laravel-mongodb still prints 5.10.0 (tagged 2 Sep 2026), or it prints:

Package "mongodb/laravel-mongodb" not found

The second one is the honest miss. Most of my CodeCanyon boxes are MySQL. If the package is absent, I am not on this CVE, and I would not write “Laravel has a Mongo injection bug” into a Slack thread.

This is a lab note from the advisory, the 5.11.0 tag, Jira PHPLARA-260, and the query-builder note the vendor shipped in that tag. I did not write a remote exploit. I did not invent a payload.

What changed

PHPLARA-260 opened 3 Aug 2026, resolved 10 Sep 2026 12:29 UTC, fix version 5.11.0. The ticket and the advisory agree on the class of bug: an array handed to an explicit equality filter was compiled as a MongoDB operator document instead of a literal value.

What I will treat as locked:

  • CVE-2026-88022 / GHSA-68xx-ccm2-m445. Affects mongodb/laravel-mongodb >= 1.0.0, < 5.11.0. Patched in 5.11.0. CVSS 8.4 (High). The three-argument where when the operator is = or eq, plus find and delete on that path.
  • Breaking change, not a silent patch. Vendor docs in the 5.11.0 tree are blunt: with 1 or 2 arguments, an array value is still a MongoDB operator document. The 3-argument form with '=' now compares as a literal. Identifier columns (_id, id, *._id) reject operator arrays. Jira’s own “Documentation Changes” block calls this a breaking change in Laravel-MongoDB 5.11.0.
  • Same tag, sibling advisories. 5.11.0 release notes also cite CVE-2026-96744 (cache lock owner, PHPLARA-261) and CVE-2026-88028 / CVE-2026-88027 (PHPLARA-265). The GitHub advisories for those last two are GHSA-54r7-f4f5-j542 (polymorphic relation identifiers, published 11 Sep 2026, affected >= 1.2.0, < 5.11.0) and GHSA-jxxg-hqjr-9h33 (embedded record keys, published 11 Sep 2026, affected >= 4.0.0, < 5.11.0). One lock bump covers the set.

What I will treat as rumor if it shows up in a “Laravel is owned” thread:

  • Laravel core. Packagist require on 5.11.0 is illuminate/* ^12|^13, php ^8.2, ext-mongodb ^1.21|^2. The CVE product is “Laravel MongoDB (PHP).” If composer why mongodb/laravel-mongodb is empty, walk away.
  • A one-line remote break-in I can paste. The advisory’s workaround is “Validate arguments.” The lab is composer audit --locked and the 2-arg vs 3-arg rewrite. I am not publishing a PoC.

PR #3581 (merged 10 Sep 2026) is the equality hardening: wrap a 3-arg '=' operator-array in $eq; reject that shape on id-like fields; keep Laravel’s where(array $conditions) shorthand working via an internal sentinel. That is the patch I would actually install.

What I would change in a real Laravel/PHP app this week

Three edits. None of them is “rewrite every query in MQL.”

1. Prove the package is in the lock. Then see the version.

composer show mongodb/laravel-mongodb
composer why mongodb/laravel-mongodb
composer audit --locked

composer audit talks to the Packagist.org advisory API by default. --locked reads composer.lock, not whatever leftover tree is in vendor/. Exit 0 means no policy hits. Exit 1 means it found something, or a required package is missing. I would not trust a green CI job that audits vendor/ after a partial deploy.

If show says the package is not found, I stop. This week’s CVE does not apply.

2. Bump the one package. Leave the framework alone.

composer update mongodb/laravel-mongodb --with-dependencies
composer show mongodb/laravel-mongodb

I want versions : * 5.11.0. As of 25 Sep 2026, Packagist still has no 5.11.1 and no 5.12.0. 5.11.0 is the patch I can cite.

3. Stop treating 2-arg and 3-arg where() as the same thing when the value is an array.

That equivalence is what 5.11.0 broke on purpose. The examples below are the vendor’s own query-builder note from the 5.11.0 tag, not a payload I invented:

use App\Models\Post;
use Illuminate\Http\Request;

public function index(Request $request)
{
    // After 5.11.0 — 3-arg '=' is a literal $eq. This is the safe form
    // for request input (vendor docs in the 5.11.0 tree).
    $status = $request->input('status');
    $posts = Post::where('status', '=', $status)->get();

    // 2-arg form is still an operator document. Intentional. Fine when I
    // wrote the array. Not fine when the array came from the request.
    $published = Post::where('status', ['$ne' => 'draft'])->get();

    // Still the wall after the bump — 2-arg + untrusted input.
    // Vendor comment on this line is "DON'T DO THIS".
    $unsafe = Post::where('status', $request->input('status'))->get();

    return [$posts, $published, $unsafe];
}

Before 5.11.0, the 3-arg '=' line compiled an array value as operators. After 5.11.0, the same line wraps that array in $eq. If I had been relying on the old compile — an array that looked like an operator document in a 3-arg call — those rows go quiet. That is the breaking change I would grep for, not a silent security win I can ignore in QA.

I would rg "->where\\(" app/ and look for two-argument calls whose second argument is $request, $input, or a variable that started as query string. I would not paste an operator-shaped array into find() to “see what happens.” The advisory already says find and delete share the equality path.

What would bite on a self-hosted VPS

First bite: the extension, not the lockfile. 5.11.0 requires ext-mongodb ^1.21 or ^2. Ubuntu 24.04 distro PHP is 8.3. The php-mongodb package from Ubuntu is not automatically that floor. Ondřej’s PPA or a PECL build is how I would get a current mongodb.so on that box. Composer’s platform check is the error I would actually get:

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - mongodb/laravel-mongodb 5.11.0 requires ext-mongodb ^1.21 || ^2

composer show mongodb/laravel-mongodb succeeding on my laptop and failing on the VPS is the classic split: laptop has the extension, the FPM pool does not. php -m | grep mongodb on the same binary Nginx uses — not the CLI I ssh into — is the check.

 2-arg where() stays an operator document; 3-arg '=' becomes literal $eq in 5.11.0

Caption: Vendor docs shipped in 5.11.0. Two-argument where($col, $array) is still MQL. Three-argument where($col, '=', $array) is now $eq. Request input belongs on the right.

Second bite: shared hosting. If the panel will not let me composer update or install ext-mongodb, I do not “patch” this by editing vendor/. I either get a VPS, or I stay on MySQL and keep the package out of the lock. There is no userland polyfill for this advisory.

Third bite: the queries that go empty after the bump. A CodeCanyon leftover that called where('meta', '=', $request->input('meta')) with an array, and treated the old operator compile as a feature, will return nothing once $eq wraps it. That looks like “the patch broke search.” It is the patch doing what Jira said it would do. I would run the app’s own list/filter screens after the update, not only composer audit.

config.platform.php stays on the FPM I serve. CI that resolves against a newer PHP than the socket will pull a ext-mongodb constraint the VPS cannot meet.

Two weeks after the tag

 Advisory timeline from PHPLARA-260 to this 25 Sep lab note

Caption: Ticket opened 3 Aug 2026. 5.11.0 and NVD on 10 Sep. GHSA-68xx on 11 Sep. I am writing 25 Sep. The patch version is still 5.11.0.

What is running in my head as the honest target this week: a Laravel 12 or 13 app that actually requires mongodb/laravel-mongodb, lock on 5.11.0, FPM and CLI both showing mongodb in php -m, and 3-arg '=' on anything that started as request input. Next check is composer outdated mongodb/laravel-mongodb if a 5.11.1 ever appears. I would not invent that tag today.

Are you on this in production?

If composer show mongodb/laravel-mongodb prints 5.11.0 and composer audit --locked is quiet for this package, you are on this. If the lock still says 5.10.0 or older, you are not — the advisory range is everything below 5.11.0 since 1.0.0. If composer show cannot find the package, you were never on this CVE; say that instead of bumping Illuminate. Shared hosting that will not give you ext-mongodb or a Composer run is the fourth camp. I did not ship a production blast tonight. I want to know which of those you are in.

Did you hit the same wall?

I would get stuck on Package "mongodb/laravel-mongodb" not found and then, on the boxes that do have it, on requires ext-mongodb ^1.21 || ^2 after the bump. Did you hit the same thing, or a different one — a 3-arg filter that went empty, composer audit green locally and red in CI, a host that will not let you update vendor/? Tell me in the comments. I read them.

References

Share:

Get new posts in your inbox

No spam. One short email per new article — practical PHP, Laravel, devops, and AI-assisted workflows.

Comments

Powered by GitHub Discussions via Giscus. A free GitHub account is required.