Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit fa1827c

Browse filesBrowse files
security #cve-2022-24894 [HttpKernel] Remove private headers before storing responses with HttpCache (nicolas-grekas)
This PR was merged into the 4.4 branch.
2 parents 3da1b76 + d2f6322 commit fa1827c
Copy full SHA for fa1827c

File tree

2 files changed

+30
-3
lines changed
Filter options

2 files changed

+30
-3
lines changed

‎src/Symfony/Component/HttpKernel/HttpCache/Store.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/HttpCache/Store.php
+17-3Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,29 @@ class Store implements StoreInterface
2626
{
2727
protected $root;
2828
private $keyCache;
29-
private $locks;
29+
private $locks = [];
30+
private $options;
3031

3132
/**
33+
* Constructor.
34+
*
35+
* The available options are:
36+
*
37+
* * private_headers Set of response headers that should not be stored
38+
* when a response is cached. (default: Set-Cookie)
39+
*
3240
* @throws \RuntimeException
3341
*/
34-
public function __construct(string $root)
42+
public function __construct(string $root, array $options = [])
3543
{
3644
$this->root = $root;
3745
if (!file_exists($this->root) && !@mkdir($this->root, 0777, true) && !is_dir($this->root)) {
3846
throw new \RuntimeException(sprintf('Unable to create the store directory (%s).', $this->root));
3947
}
4048
$this->keyCache = new \SplObjectStorage();
41-
$this->locks = [];
49+
$this->options = array_merge([
50+
'private_headers' => ['Set-Cookie'],
51+
], $options);
4252
}
4353

4454
/**
@@ -215,6 +225,10 @@ public function write(Request $request, Response $response)
215225
$headers = $this->persistResponse($response);
216226
unset($headers['age']);
217227

228+
foreach ($this->options['private_headers'] as $h) {
229+
unset($headers[strtolower($h)]);
230+
}
231+
218232
array_unshift($entries, [$storedEnv, $headers]);
219233

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

‎src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php
+13Lines changed: 13 additions & 0 deletions
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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.