Caption: composer show first. Then composer audit --locked. Then getBaseUrl() on a throwaway Request. Illuminate always pulls symfony/http-foundation. Do not invent a CVE id.
I did not send a crafted //host URL at anything tonight. I opened Ubuntu 24.04.5, installed archive php8.3-cli, and ran throwaway composer require of two tags. php -v printed PHP 8.3.6, built 19 Oct 2026. PHP_VERSION_ID is 80306. Package 8.3.6-0ubuntu0.24.04.13. There is no php-fpm on this box. Distro Composer is still 2.7.1-2.
On 7.4.22, Request::getBaseUrl() returned //evil.example/public/index.php while getHost() stayed app.example. On 7.4.23 the same constructor returned an empty base URL. composer audit on 7.4.22 printed four advisories. On 7.4.23 it printed No security vulnerability advisories found.
That is the wall this week. APP_URL and framework.trusted_hosts do not close it — the advisory says the request host stays the real one. Laravel 13.42.0 (10 Nov 2026) still requires symfony/http-foundation: ^7.4.0 || ^8.0.0. This is a Composer component advisory. It is not laravel/framework. The GitHub advisory has no CVE id. I will not invent one.
What changed
Symfony’s GHSA-5mx8 blog is dated 4 Nov 2026. GHSA-5mx8-mwrp-5693 published the same day. Package: symfony/http-foundation. Severity Moderate. CWE-601 and CWE-829. The advisory table has no CVE. Packagist PKSA-b2gg-vk1g-6d5q (reportedAt 2026-11-04 00:00:00) is the same write-up.
What I will treat as locked this week:
Request::getBaseUrl()kept a client-chosen prefix. When it does not find the script name at the start of the request URI, it looks further into the path — the support path for a front controller in a subdirectory. A URI that starts with//or/\made that prefix start with a host. WithSCRIPT_NAME=/public/index.php, the advisory’s example request for//evil.example/public/index.php/loginis routed to/login, with base URL//evil.example/public/index.phpand base path//evil.example/public. Generatedpath()links, form actions,redirectToRoute()targets, and relativeasset()URLs then point at that host. The user has to follow a crafted link.trusted_hostsdoes not help.- Patched floors are 5.4.56 / 6.4.50 / 7.4.23 / 8.1.11. Affected (GHSA):
<5.4.56,>=6 <6.4.50,>=7 <7.4.23,>=8 <8.1.11. Resolution:getBaseUrl()now returns empty when the request URI starts with//or/\. Forward-ported to 8.2 in the advisory. Packagist still has 8.2.0-BETA1 only (time2026-11-04T08:52:03Z). symfony.com/releases still lists 8.2 as Under development, November 2026 (retrieved 13 Nov 2026). I will not pin a beta. - Packagist
timeon the four floors, 4 Nov 2026: 5.4.5607:37:33Z, 6.4.5008:16:31Z, 7.4.2308:27:22Z, 8.1.1108:39:20Z. GitHubsymfony/http-foundationtags the same day: v5.4.56 10:52 UTC, v6.4.50 11:25, v7.4.23 11:29, v8.1.11 11:32. Symfony blogs: 6.4.50 and 7.4.23 on 4 Nov; 8.1.11 metapackage on 5 Nov. The 6.4.50 post says 6.4.50 is the last version for the 6.4 branch (bug fixes until November 2026; security until November 2027). - No later stable tag I can cite. Packagist retrieved 13 Nov 2026: no 8.1.12, no 7.4.24, no 6.4.51, no 5.4.57, no 8.2.0. 8.1.11 needs PHP >= 8.4.1; this 8.3.6 box cannot take it. The 7.4 line is PHP >= 8.2.
- Laravel always pulls this package. laravel/framework 13.42.0 (
time2026-11-10T15:54:30Z) still requiressymfony/http-foundation: ^7.4.0 || ^8.0.0. Not a Laravel-core CVE. A CodeCanyon leftover on Laravel 12 will still have the component.composer showis the check.
What I will treat as rumor: Illuminate having a CVE; APP_URL as the patch; Symfony 8.2 as a GA I can pin; a CVE id for GHSA-5mx8; apt upgrade on Ubuntu 24.04 fixing this (distro PHP is still 8.3.6; HttpFoundation is Composer).
Same-day siblings on the same http-foundation tags, only if you are reading this lock: GHSA-3h27-hjv7-fqjx (Low; getPathInfo() stripped a script-name prefix from /index.phpadmin; no CVE); CVE-2026-118514 / GHSA-jrf8-gvm4-7cgh (Moderate 6.3; HEAD bypasses GET-only RequestMatcher / access_control; Symfony blog 4 Nov, NVD listed 6 Nov; Laravel rarely uses Symfony Security access_control); GHSA-xg2q-4rrq-657q (private_ranges trusted proxies; Moderate 6.3; http-foundation >=7.2 <7.4.23 and >=8 <8.1.11). The 4 Nov dump also tagged Serializer / Routing / HtmlSanitizer CVEs — composer show those packages; do not invent they ship in Laravel core. This blog’s lib/ pulled yaml 7.4.23 via Spatie and has no http-foundation. I asked composer show. That is not a Laravel app.
What I would change in a real Laravel/PHP app this week
Three edits. None of them is “paste a //host URL at production.”
1. Prove the lock. Then run the getBaseUrl lab. Do not send a crafted URI at a live app.
php -v
php-fpm8.3 -v # the pool Nginx uses, not the CLI I wish I had
composer show symfony/http-foundation
composer why symfony/http-foundation
composer audit --locked
composer audit talks to Packagist by default. --locked reads composer.lock. Exit 0 means no policy hits. Exit 1 means it found something. On this 8.3.6 CLI, throwaway 7.4.22 printed four rows (GHSA-5mx8 with NO CVE, GHSA-3h27, GHSA-xg2q, CVE-2026-118514). Throwaway 7.4.23 printed none. Composer 2.7.1 was enough to see that.
Then the before, on the binary that actually served the last request. Request::create('//evil.example/...') is the wrong constructor here — it parsed the host as evil.example. The advisory case keeps HTTP_HOST as the real app and puts // on REQUEST_URI:
use Symfony\Component\HttpFoundation\Request;
$server = [
'HTTP_HOST' => 'app.example',
'REQUEST_URI' => '//evil.example/public/index.php/login',
'SCRIPT_NAME' => '/public/index.php',
'SCRIPT_FILENAME' => '/var/www/app/public/index.php',
'REQUEST_METHOD' => 'GET',
];
$req = new Request([], [], [], [], [], $server);
var_export($req->getBaseUrl());
echo PHP_EOL, 'host=', $req->getHost(), PHP_EOL;
echo 'pathInfo=', $req->getPathInfo(), PHP_EOL;
On this box that printed:
PHP 8.3.6 (cli) (built: Oct 19 2026)
# throwaway composer require symfony/http-foundation:7.4.22
'//evil.example/public/index.php'
host=app.example
pathInfo=/login
# same tree, 7.4.23
''
host=app.example
pathInfo=//evil.example/public/index.php/login
Empty base URL is the fix. A base URL that starts with // is 7.4.22. getHost() stayed app.example on both tags — that is why trusted_hosts does not close it. I would not ask a browser to follow that URI.
2. Bump to the floor for the line I actually lock. Reload FPM.
# PHP 8.3 VPS — Laravel 13 will resolve the 7.4 line.
composer update symfony/http-foundation --with-dependencies
composer show symfony/http-foundation
# versions : * v7.4.23
# PHP 8.4+ only — 8.1.11 requires >=8.4.1
# composer show will print v8.1.11 when the platform allows it
sudo systemctl reload php8.3-fpm
As of 13 Nov 2026 I still want 7.4.23, 6.4.50, 8.1.11, or 5.4.56. I would not invent 8.1.12. I would not install 8.2.0-BETA1.
3. Gate any leftover that constructs a Request on an old lock. Do not call this a Laravel CVE.
use Composer\InstalledVersions;
use Symfony\Component\HttpFoundation\Request;
function httpFoundationGhsa5mx8FloorMet(): bool
{
if (! InstalledVersions::isInstalled('symfony/http-foundation')) {
return false;
}
$v = ltrim(InstalledVersions::getPrettyVersion('symfony/http-foundation'), 'v');
if ($v === '' || preg_match('/(?:alpha|beta|rc|dev)/i', $v)) {
return false;
}
return match (true) {
str_starts_with($v, '8.') => version_compare($v, '8.1.11', '>='),
str_starts_with($v, '7.') => version_compare($v, '7.4.23', '>='),
str_starts_with($v, '6.') => version_compare($v, '6.4.50', '>='),
str_starts_with($v, '5.') => version_compare($v, '5.4.56', '>='),
default => false,
};
}
// Before — generated path() / form action used getBaseUrl() as-is.
// $request = Request::createFromGlobals();
// url('/login');
// After — brake until the lock is on a floor tag. The patch is Composer, not this if.
if (! httpFoundationGhsa5mx8FloorMet()) {
abort(503, 'HttpFoundation below GHSA-5mx8-mwrp-5693 floor.');
}
$request = Request::createFromGlobals();
I ran that helper here. 7.4.22 / 8.1.10 / 6.4.49 / 5.4.54 / 8.2.0-BETA1 → false. 7.4.23 / 8.1.11 / 6.4.50 / 5.4.56 → true. That 503 is a brake. The patch is the lockfile. If I am already on 7.4.23 I delete the gate. I would still composer show symfony/yaml, symfony/routing, symfony/serializer, and symfony/html-sanitizer once. Absent packages are not those 4 Nov CVEs.
What would bite on a self-hosted VPS
Caption: composer show then composer audit --locked. Then getBaseUrl() with SCRIPT_NAME=/public/index.php and a REQUEST_URI that starts with //. Empty string is the fix. A //host/... base URL is 7.4.22. Do not send that URI at a live app.
First bite: a root .htaccess that rewrites everything into public/. The advisory names that layout, nginx without fastcgi_split_path_info, and php -S with a router outside the document root. Symfony’s documented configs are not affected. I would still bump. A Laravel VPS that points Nginx at public/ the way the Laravel nginx gist does is the safer layout — it is not a reason to stay on 7.4.22.
Second bite: PHP 8.3 vs 8.4 on the same app. Laravel 13 advertises 8.3–8.5. 8.1.11 will not install on this 8.3.6 CLI. config.platform.php set to 8.4 on a laptop, and FPM still on 8.3, is how I get a lock the VPS cannot install. The error I actually expect:
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Root composer.json requires php >=8.4.1 (because 8.1.11 said so)
I would pin the 7.4 line on an 8.3 box: composer require "symfony/http-foundation:^7.4.23". I would not invent that apt will give me PHP 8.4 this afternoon.
Third bite: shared hosting and leftover vendor/. If the panel will not let me composer update, I do not edit Request.php in place. There is no userland polyfill for this advisory on a shared-hosting panel that blocks Composer. Rsync an old vendor/ after a green laptop audit and FPM still runs 7.4.22. OPcache keeps the old class until I reload the pool Nginx actually uses. This lab has no FPM; the command I would type on a real VPS is still php-fpm8.3 -v then systemctl reload.
Nine days after the advisory
Caption: Packagist floors 4 Nov 2026. GHSA published the same day, Moderate, no CVE. 8.1.11 metapackage blog 5 Nov. I am writing 13 Nov. Packagist still has 8.1.11 / 7.4.23 / 6.4.50 / 5.4.56 as latest. No 8.1.12. 8.2 is still BETA1.
Symfony’s 6.4 page still lists 6.4.50 as latest 6.4, last bugfix tag, security until November 2027 (retrieved 13 Nov 2026). Stable current is 8.1.11. LTS current is 7.4.23. Honest target this week: Laravel 13 on PHP 8.3 FPM, lock on http-foundation 7.4.23, getBaseUrl() empty on that REQUEST_URI, CLI and the socket on the same PHP. If the box is already 8.4, 8.1.11. I would not invent the next Thursday tag today.
Are you on this in production?
If composer show symfony/http-foundation already prints 7.4.23 (or 6.4.50 / 8.1.11 / 5.4.56 on that line) and getBaseUrl() returns empty on the lab constructor, you are on this. If audit is red on 7.4.22 and the lock still says that tag, you are not. If CLI shows 7.4.23 and the deployed vendor/ is still 7.4.22, you are not. Shared hosting that will not run Composer is the fourth camp. I did not flip a client cluster tonight. I want to know which of those you are in.
Did you hit the same wall?
I would get stuck on getBaseUrl() returning //evil.example/public/index.php on 7.4.22 while getHost() stayed app.example, or on Composer blocking 8.1.11 because this VPS is PHP 8.3.6. Did you hit the same thing, or a different one — a root .htaccess rewrite into public/, nginx without fastcgi_split_path_info, a lock that jumped to Symfony 8 on a laptop with 8.4, a host that will not let you update vendor/? Tell me in the comments. I read them.
If the blocker is the VPS itself (wrong PHP floor, a panel that will not run Composer, a socket that still loads old vendor/), I do this class of bump for a living: Hire for deploy.
References
- Symfony GHSA-5mx8-mwrp-5693 blog (4 Nov 2026): https://symfony.com/blog/ghsa-5mx8-mwrp-5693-generated-urls-can-point-to-a-host-chosen-by-the-client
- GHSA-5mx8-mwrp-5693 (published 4 Nov 2026), Moderate, no CVE id,
symfony/http-foundation: https://github.com/symfony/symfony/security/advisories/GHSA-5mx8-mwrp-5693 - Packagist advisory PKSA-b2gg-vk1g-6d5q (
reportedAt2026-11-04; no CVE): https://packagist.org/api/security-advisories/?packages[]=symfony/http-foundation - Symfony 5.4.56 released (4 Nov 2026): https://symfony.com/blog/symfony-5-4-56-released
- Symfony 6.4.50 released (4 Nov 2026; last 6.4 bugfix tag): https://symfony.com/blog/symfony-6-4-50-released
- Symfony 7.4.23 released (4 Nov 2026): https://symfony.com/blog/symfony-7-4-23-released
- Symfony 8.1.11 released (5 Nov 2026): https://symfony.com/blog/symfony-8-1-11-released
- GitHub
symfony/http-foundationv5.4.56 (4 Nov 2026 10:52 UTC): https://github.com/symfony/http-foundation/releases/tag/v5.4.56 - GitHub
symfony/http-foundationv6.4.50 (4 Nov 2026 11:25 UTC): https://github.com/symfony/http-foundation/releases/tag/v6.4.50 - GitHub
symfony/http-foundationv7.4.23 (4 Nov 2026 11:29 UTC): https://github.com/symfony/http-foundation/releases/tag/v7.4.23 - GitHub
symfony/http-foundationv8.1.11 (4 Nov 2026 11:32 UTC): https://github.com/symfony/http-foundation/releases/tag/v8.1.11 - Packagist
symfony/http-foundation(8.1.11time2026-11-04T08:39:20+00:00; 7.4.23 2026-11-04T08:27:22+00:00; 6.4.50 2026-11-04T08:16:31+00:00; 5.4.56 2026-11-04T07:37:33+00:00; 8.2.0-BETA1 2026-11-04T08:52:03+00:00; retrieved 13 Nov 2026): https://packagist.org/packages/symfony/http-foundation - Symfony releases (stable 8.1.11; LTS 7.4.23; 6.4 6.4.50; 8.2 under development; retrieved 13 Nov 2026): https://symfony.com/releases
- Packagist
laravel/framework13.42.0 (2026-11-10;symfony/http-foundation: ^7.4.0 || ^8.0.0): https://packagist.org/packages/laravel/framework - Laravel 13 release notes (PHP 8.3–8.5, released 17 Mar 2026): https://laravel.com/docs/13.x/releases
- Composer
audit(--locked; exit 0 / 1): https://getcomposer.org/doc/03-cli.md#audit - GHSA-3h27-hjv7-fqjx (published 4 Nov 2026), Low, no CVE: https://github.com/symfony/symfony/security/advisories/GHSA-3h27-hjv7-fqjx
- Symfony CVE-2026-118514 blog (4 Nov 2026): https://symfony.com/blog/cve-2026-118514-head-requests-bypass-the-methods-option-of-access-control-and-firewalls-incomplete-fix-for-cve-2026-45075
- GHSA-jrf8-gvm4-7cgh (published 4 Nov 2026), CVSS 6.3: https://github.com/symfony/symfony/security/advisories/GHSA-jrf8-gvm4-7cgh
- NVD CVE-2026-118514 (listed 6 Nov 2026): https://nvd.nist.gov/vuln/detail/CVE-2026-118514
- GHSA-xg2q-4rrq-657q (published 4 Nov 2026), CVSS 6.3: https://github.com/symfony/symfony/security/advisories/GHSA-xg2q-4rrq-657q