-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Description
Tested on 2.4.0, 2.5.9, 2.6.3
As you know, when creating a Response object it will default have Cache-control: no-cache
as a default header to prevent caching. Response::prepare()
tweaks the response object to be RFC 2616 compliant, which sets a variety of cache-related headers for maximum compatibility in this context. Specifically, expires: -1
and pragma: no-cache
.
However, by invoking prepare()
, the Cache-control
header is recomputed to private, must-revalidate
, removing the no-cache
directive required to not cache in Chrome (tested on ver. 39.0.2171.95). This introduced a security vulnerability in my app whereby pressing the back button after logging out of an authenticated resource caused the browser to load sensitive information from its cache.
Sample program illustrating bug below:
<?php
require 'vendor/autoload.php';
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
$request = Request::createFromGlobals();
$response = new Response('Test', 200, array('Content-Type' => 'text/plain'));
// Defaults to "no-cache" directive in "Cache-control:" header, as expected
var_dump($response->headers->all());
$response->prepare($request);
// "no-cache" directive in "Cache-control" header is now missing. Pressing the
// Back button after navigating away from this page will load it from browser
// cache.
var_dump($response->headers->all());
var_dump($response->isCacheable()); // returns "true"