Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit edb3d26

Browse files
committed
Do not send deleted session cookie twice in the response
1 parent 91b7bdd commit edb3d26

File tree

4 files changed

+78
-1
lines changed

4 files changed

+78
-1
lines changed

src/Symfony/Component/HttpFoundation/Session/SessionUtils.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ public static function popSessionCookie(string $sessionName, string $sessionId):
3030
$sessionCookie = null;
3131
$sessionCookiePrefix = sprintf(' %s=', urlencode($sessionName));
3232
$sessionCookieWithId = sprintf('%s%s;', $sessionCookiePrefix, urlencode($sessionId));
33+
// PHP internally sets the session cookie value to "deleted" when setcookie() is called with empty string $value argument
34+
// which happens in \Symfony\Component\HttpFoundation\Session\Storage\Handler\AbstractSessionHandler::destroy
35+
// when the session gets invalidated (for example on logout) so we must handle this case here too
36+
$sessionCookieWithDeletedId = sprintf('%s%s;', $sessionCookiePrefix, 'deleted');
3337
$otherCookies = [];
3438
foreach (headers_list() as $h) {
3539
if (0 !== stripos($h, 'Set-Cookie:')) {
@@ -38,7 +42,7 @@ public static function popSessionCookie(string $sessionName, string $sessionId):
3842
if (11 === strpos($h, $sessionCookiePrefix, 11)) {
3943
$sessionCookie = $h;
4044

41-
if (11 !== strpos($h, $sessionCookieWithId, 11)) {
45+
if (11 !== strpos($h, $sessionCookieWithId, 11) && 11 !== strpos($h, $sessionCookieWithDeletedId, 11)) {
4246
$otherCookies[] = $h;
4347
}
4448
} else {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
Array
3+
(
4+
[0] => Content-Type: text/plain; charset=utf-8
5+
[1] => Cache-Control: max-age=0, private, must-revalidate
6+
[2] => Cache-Control: max-age=0, must-revalidate, private
7+
[3] => Date: Sat, 12 Nov 1955 20:04:00 GMT
8+
[4] => Expires: %s, %d %s %d %d:%d:%d GMT
9+
[5] => Set-Cookie: PHPSESSID=deleted; expires=%s, %d-%s-%d %d:%d:%d GMT; Max-Age=%d; %s
10+
)
11+
shutdown
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
use Symfony\Component\DependencyInjection\Container;
4+
use Symfony\Component\HttpFoundation\Request;
5+
use Symfony\Component\HttpFoundation\RequestStack;
6+
use Symfony\Component\HttpFoundation\Response;
7+
use Symfony\Component\HttpFoundation\Session\SessionFactory;
8+
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorageFactory;
9+
use Symfony\Component\HttpKernel\Event\RequestEvent;
10+
use Symfony\Component\HttpKernel\Event\ResponseEvent;
11+
use Symfony\Component\HttpKernel\EventListener\SessionListener;
12+
use Symfony\Component\HttpKernel\HttpKernelInterface;
13+
14+
/** @var Response $r */
15+
$r = require __DIR__.'/common.inc';
16+
17+
$sessionId = 'vqd4dpbtst3af0k4sdl18nebkn';
18+
session_id($sessionId);
19+
$sessionName = session_name();
20+
$_COOKIE[$sessionName] = $sessionId;
21+
22+
$request = new Request();
23+
$request->cookies->set($sessionName, $sessionId);
24+
25+
$requestStack = new RequestStack();
26+
$requestStack->push($request);
27+
28+
$sessionFactory = new SessionFactory($requestStack, new NativeSessionStorageFactory());
29+
30+
$container = new Container();
31+
$container->set('request_stack', $requestStack);
32+
$container->set('session_factory', $sessionFactory);
33+
34+
$listener = new SessionListener($container);
35+
36+
$kernel = new class($r) implements HttpKernelInterface {
37+
/**
38+
* @var Response
39+
*/
40+
private $response;
41+
42+
public function __construct(Response $response)
43+
{
44+
$this->response = $response;
45+
}
46+
47+
public function handle(Request $request, int $type = self::MAIN_REQUEST, bool $catch = true)
48+
{
49+
return $this->response;
50+
}
51+
};
52+
53+
$listener->onKernelRequest(new RequestEvent($kernel, $request, HttpKernelInterface::MAIN_REQUEST));
54+
$session = $request->getSession();
55+
$session->set('foo', 'bar');
56+
$session->invalidate();
57+
58+
$listener->onKernelResponse(new ResponseEvent($kernel, $request, HttpKernelInterface::MAIN_REQUEST, $r));
59+
60+
$r->sendHeaders();

src/Symfony/Component/HttpFoundation/composer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
"require-dev": {
2525
"predis/predis": "~1.0",
2626
"symfony/cache": "^4.4|^5.0|^6.0",
27+
"symfony/dependency-injection": "^5.4|^6.0",
28+
"symfony/http-kernel": "^5.4|^6.0",
2729
"symfony/mime": "^4.4|^5.0|^6.0",
2830
"symfony/expression-language": "^4.4|^5.0|^6.0"
2931
},

0 commit comments

Comments
 (0)