-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Closed
Description
Symfony version(s) affected
6.2 and probably before
Description
The CachingHttpClient creates a new Request object, then uses it to call the decorated HttpClient.
Sadly, the Request class contains a static variable with the list of trusted hosts. Usually defined in the front controller or via parameters.
When someone uses the CachingHttpClient to call an external endpoint (not trusted), the request removes the Host part of the URL, leading to an invalid URL
How to reproduce
minimal reproducer
<?php
use Symfony\Component\HttpClient\CachingHttpClient;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpCache\Store;
include __DIR__.'/vendor/autoload.php';
Request::setTrustedHosts(['notsymfony.com']);
$client = new CachingHttpClient(HttpClient::create(), new Store('/tmp/xxx'));
$response = $client->request('GET', 'https://symfony.com/foo');
echo $response->getStatusCode();returns
PHP Fatal error: Uncaught Symfony\Component\HttpClient\Exception\InvalidArgumentException: Malformed URL "https:///foo". in /data/oss/test/vendor/symfony/http-client/HttpClientTrait.php:505
Stack trace:
#0 /data/oss/test/vendor/symfony/http-client/HttpClientTrait.php(169): Symfony\Component\HttpClient\CurlHttpClient::parseUrl()
#1 /data/oss/test/vendor/symfony/http-client/CurlHttpClient.php(87): Symfony\Component\HttpClient\CurlHttpClient::prepareRequest()
#2 /data/oss/test/vendor/symfony/http-kernel/HttpClientKernel.php(53): Symfony\Component\HttpClient\CurlHttpClient->request()
#3 /data/oss/test/vendor/symfony/http-kernel/HttpCache/SubRequestHandler.php(86): Symfony\Component\HttpKernel\HttpClientKernel->handle()
#4 /data/oss/test/vendor/symfony/http-kernel/HttpCache/HttpCache.php(464): Symfony\Component\HttpKernel\HttpCache\SubRequestHandler::handle()
#5 /data/oss/test/vendor/symfony/http-kernel/HttpCache/HttpCache.php(264): Symfony\Component\HttpKernel\HttpCache\HttpCache->forward()
#6 /data/oss/test/vendor/symfony/http-kernel/HttpCache/HttpCache.php(331): Symfony\Component\HttpKernel\HttpCache\HttpCache->pass()
#7 /data/oss/test/vendor/symfony/http-kernel/HttpCache/HttpCache.php(215): Symfony\Component\HttpKernel\HttpCache\HttpCache->lookup()
#8 /data/oss/test/vendor/symfony/http-client/CachingHttpClient.php(98): Symfony\Component\HttpKernel\HttpCache\HttpCache->handle()
#9 /data/oss/test/index.php(12): Symfony\Component\HttpClient\CachingHttpClient->request()
#10 {main}
thrown in /data/oss/test/vendor/symfony/http-client/HttpClientTrait.php on line 505
Possible Solution
🤷
- Long solution: remove global state from request in order to use the object for non-incoming requests + without side effects
- Short solution: In the
CachingHttpClientamends the list of trustedHost with the requested host
Additional Context
No response