VYPR
Low severityNVD Advisory· Published Mar 30, 2020· Updated Aug 4, 2024

Prevent cache poisoning via a Response Content-Type header

CVE-2020-5255

Description

In Symfony before versions 4.4.7 and 5.0.7, when a Response does not contain a Content-Type header, affected versions of Symfony can fallback to the format defined in the Accept header of the request, leading to a possible mismatch between the response's content and Content-Type header. When the response is cached, this can prevent the use of the website by other users. This has been patched in versions 4.4.7 and 5.0.7.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
symfony/http-foundationPackagist
>= 4.4.0, < 4.4.74.4.7
symfony/http-foundationPackagist
>= 5.0.0, < 5.0.75.0.7
symfony/symfonyPackagist
>= 4.4.0, < 4.4.74.4.7
symfony/symfonyPackagist
>= 5.0.0, < 5.0.75.0.7

Affected products

1

Patches

1
dca343442e6a

security #cve-2020-5255 [HttpFoundation] Do not set the default Content-Type based on the Accept header (yceruto)

https://github.com/symfony/symfonyNicolas GrekasMar 30, 2020via ghsa
4 files changed · +26 4
  • src/Symfony/Component/ErrorHandler/ErrorRenderer/SerializerErrorRenderer.php+8 1 modified
    @@ -12,6 +12,7 @@
     namespace Symfony\Component\ErrorHandler\ErrorRenderer;
     
     use Symfony\Component\ErrorHandler\Exception\FlattenException;
    +use Symfony\Component\HttpFoundation\Request;
     use Symfony\Component\HttpFoundation\RequestStack;
     use Symfony\Component\Serializer\Exception\NotEncodableValueException;
     use Symfony\Component\Serializer\SerializerInterface;
    @@ -30,6 +31,7 @@ class SerializerErrorRenderer implements ErrorRendererInterface
     
         /**
          * @param string|callable(FlattenException) $format The format as a string or a callable that should return it
    +     *                                                  formats not supported by Request::getMimeTypes() should be given as mime types
          * @param bool|callable                     $debug  The debugging mode as a boolean or a callable that should return it
          */
         public function __construct(SerializerInterface $serializer, $format, ErrorRendererInterface $fallbackErrorRenderer = null, $debug = false)
    @@ -57,11 +59,16 @@ public function render(\Throwable $exception): FlattenException
     
             try {
                 $format = \is_string($this->format) ? $this->format : ($this->format)($flattenException);
    +            $headers = [
    +                'Content-Type' => Request::getMimeTypes($format)[0] ?? $format,
    +                'Vary' => 'Accept',
    +            ];
     
                 return $flattenException->setAsString($this->serializer->serialize($flattenException, $format, [
                     'exception' => $exception,
                     'debug' => \is_bool($this->debug) ? $this->debug : ($this->debug)($exception),
    -            ]));
    +            ]))
    +            ->setHeaders($flattenException->getHeaders() + $headers);
             } catch (NotEncodableValueException $e) {
                 return $this->fallbackErrorRenderer->render($exception);
             }
    
  • src/Symfony/Component/HttpFoundation/Request.php+3 1 modified
    @@ -1590,7 +1590,9 @@ public function isNoCache()
          * Gets the preferred format for the response by inspecting, in the following order:
          *   * the request format set using setRequestFormat
          *   * the values of the Accept HTTP header
    -     *   * the content type of the body of the request.
    +     *
    +     * Note that if you use this method, you should send the "Vary: Accept" header
    +     * in the response to prevent any issues with intermediary HTTP caches.
          */
         public function getPreferredFormat(?string $default = 'html'): ?string
         {
    
  • src/Symfony/Component/HttpFoundation/Response.php+1 1 modified
    @@ -275,7 +275,7 @@ public function prepare(Request $request)
             } else {
                 // Content-type based on the Request
                 if (!$headers->has('Content-Type')) {
    -                $format = $request->getPreferredFormat(null);
    +                $format = $request->getRequestFormat(null);
                     if (null !== $format && $mimeType = $request->getMimeType($format)) {
                         $headers->set('Content-Type', $mimeType);
                     }
    
  • src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php+14 1 modified
    @@ -497,12 +497,25 @@ public function testPrepareDoesNothingIfRequestFormatIsNotDefined()
             $this->assertEquals('text/html; charset=UTF-8', $response->headers->get('content-type'));
         }
     
    +    /**
    +     * Same URL cannot produce different Content-Type based on the value of the Accept header,
    +     * unless explicitly stated in the response object.
    +     */
    +    public function testPrepareDoesNotSetContentTypeBasedOnRequestAcceptHeader()
    +    {
    +        $response = new Response('foo');
    +        $request = Request::create('/');
    +        $request->headers->set('Accept', 'application/json');
    +        $response->prepare($request);
    +
    +        $this->assertSame('text/html; charset=UTF-8', $response->headers->get('content-type'));
    +    }
    +
         public function testPrepareSetContentType()
         {
             $response = new Response('foo');
             $request = Request::create('/');
             $request->setRequestFormat('json');
    -        $request->headers->remove('accept');
     
             $response->prepare($request);
     
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

10

News mentions

0

No linked articles in our index yet.