Skip to content

Commit c37b7dd

Browse files
Merge branch '4.4' into 5.4
* 4.4: [Security/Http] Remove CSRF tokens from storage on successful login [HttpKernel] Remove private headers before storing responses with HttpCache
2 parents 441e106 + f7822a7 commit c37b7dd

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

HttpCache/Store.php

+16-1
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,28 @@ class Store implements StoreInterface
2929
private $keyCache;
3030
/** @var array<string, resource> */
3131
private $locks = [];
32+
private $options;
3233

3334
/**
35+
* Constructor.
36+
*
37+
* The available options are:
38+
*
39+
* * private_headers Set of response headers that should not be stored
40+
* when a response is cached. (default: Set-Cookie)
41+
*
3442
* @throws \RuntimeException
3543
*/
36-
public function __construct(string $root)
44+
public function __construct(string $root, array $options = [])
3745
{
3846
$this->root = $root;
3947
if (!is_dir($this->root) && !@mkdir($this->root, 0777, true) && !is_dir($this->root)) {
4048
throw new \RuntimeException(sprintf('Unable to create the store directory (%s).', $this->root));
4149
}
4250
$this->keyCache = new \SplObjectStorage();
51+
$this->options = array_merge([
52+
'private_headers' => ['Set-Cookie'],
53+
], $options);
4354
}
4455

4556
/**
@@ -216,6 +227,10 @@ public function write(Request $request, Response $response)
216227
$headers = $this->persistResponse($response);
217228
unset($headers['age']);
218229

230+
foreach ($this->options['private_headers'] as $h) {
231+
unset($headers[strtolower($h)]);
232+
}
233+
219234
array_unshift($entries, [$storedEnv, $headers]);
220235

221236
if (!$this->save($key, serialize($entries))) {

Tests/HttpCache/StoreTest.php

+13
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
namespace Symfony\Component\HttpKernel\Tests\HttpCache;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\HttpFoundation\Cookie;
1516
use Symfony\Component\HttpFoundation\Request;
1617
use Symfony\Component\HttpFoundation\Response;
18+
use Symfony\Component\HttpKernel\HttpCache\HttpCache;
1719
use Symfony\Component\HttpKernel\HttpCache\Store;
1820

1921
class StoreTest extends TestCase
@@ -317,6 +319,17 @@ public function testPurgeHttpAndHttps()
317319
$this->assertEmpty($this->getStoreMetadata($requestHttps));
318320
}
319321

322+
public function testDoesNotStorePrivateHeaders()
323+
{
324+
$request = Request::create('https://example.com/foo');
325+
$response = new Response('foo');
326+
$response->headers->setCookie(Cookie::fromString('foo=bar'));
327+
328+
$this->store->write($request, $response);
329+
$this->assertArrayNotHasKey('set-cookie', $this->getStoreMetadata($request)[0][1]);
330+
$this->assertNotEmpty($response->headers->getCookies());
331+
}
332+
320333
protected function storeSimpleEntry($path = null, $headers = [])
321334
{
322335
if (null === $path) {

0 commit comments

Comments
 (0)