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 23bd7a7

Browse filesBrowse files
simonchrzfabpot
authored andcommitted
[HttpFoundation] Take php session.cookie settings into account
1 parent 646c33f commit 23bd7a7
Copy full SHA for 23bd7a7

File tree

2 files changed

+122
-8
lines changed
Filter options

2 files changed

+122
-8
lines changed

‎src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php
+26-6Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,12 @@ public function onKernelResponse(ResponseEvent $event)
140140
*/
141141
$sessionName = $session->getName();
142142
$sessionId = $session->getId();
143-
$sessionCookiePath = $this->sessionOptions['cookie_path'] ?? '/';
144-
$sessionCookieDomain = $this->sessionOptions['cookie_domain'] ?? null;
145-
$sessionCookieSecure = $this->sessionOptions['cookie_secure'] ?? false;
146-
$sessionCookieHttpOnly = $this->sessionOptions['cookie_httponly'] ?? true;
147-
$sessionCookieSameSite = $this->sessionOptions['cookie_samesite'] ?? Cookie::SAMESITE_LAX;
143+
$sessionOptions = $this->getSessionOptions($this->sessionOptions);
144+
$sessionCookiePath = $sessionOptions['cookie_path'] ?? '/';
145+
$sessionCookieDomain = $sessionOptions['cookie_domain'] ?? null;
146+
$sessionCookieSecure = $sessionOptions['cookie_secure'] ?? false;
147+
$sessionCookieHttpOnly = $sessionOptions['cookie_httponly'] ?? true;
148+
$sessionCookieSameSite = $sessionOptions['cookie_samesite'] ?? Cookie::SAMESITE_LAX;
148149

149150
SessionUtils::popSessionCookie($sessionName, $sessionId);
150151

@@ -162,7 +163,7 @@ public function onKernelResponse(ResponseEvent $event)
162163
);
163164
} elseif ($sessionId !== $requestSessionCookieId) {
164165
$expire = 0;
165-
$lifetime = $this->sessionOptions['cookie_lifetime'] ?? null;
166+
$lifetime = $sessionOptions['cookie_lifetime'] ?? null;
166167
if ($lifetime) {
167168
$expire = time() + $lifetime;
168169
}
@@ -280,4 +281,23 @@ public function reset(): void
280281
* @return SessionInterface|null
281282
*/
282283
abstract protected function getSession();
284+
285+
private function getSessionOptions(array $sessionOptions): array
286+
{
287+
$mergedSessionOptions = [];
288+
289+
foreach (session_get_cookie_params() as $key => $value) {
290+
$mergedSessionOptions['cookie_'.$key] = $value;
291+
}
292+
293+
foreach ($sessionOptions as $key => $value) {
294+
// do the same logic as in the NativeSessionStorage
295+
if ('cookie_secure' === $key && 'auto' === $value) {
296+
continue;
297+
}
298+
$mergedSessionOptions[$key] = $value;
299+
}
300+
301+
return $mergedSessionOptions;
302+
}
283303
}

‎src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php
+96-2Lines changed: 96 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Psr\Log\LoggerInterface;
1616
use Symfony\Component\DependencyInjection\Container;
1717
use Symfony\Component\DependencyInjection\ServiceLocator;
18+
use Symfony\Component\HttpFoundation\Cookie;
1819
use Symfony\Component\HttpFoundation\Request;
1920
use Symfony\Component\HttpFoundation\RequestStack;
2021
use Symfony\Component\HttpFoundation\Response;
@@ -33,6 +34,99 @@
3334

3435
class SessionListenerTest extends TestCase
3536
{
37+
/**
38+
* @dataProvider provideSessionOptions
39+
* @runInSeparateProcess
40+
*/
41+
public function testSessionCookieOptions(array $phpSessionOptions, array $sessionOptions, array $expectedSessionOptions)
42+
{
43+
$session = $this->getMockBuilder(Session::class)->disableOriginalConstructor()->getMock();
44+
$session->expects($this->exactly(2))->method('getUsageIndex')->will($this->onConsecutiveCalls(0, 1));
45+
$session->expects($this->exactly(1))->method('getId')->willReturn('123456');
46+
$session->expects($this->exactly(1))->method('getName')->willReturn('PHPSESSID');
47+
$session->expects($this->exactly(1))->method('save');
48+
$session->expects($this->exactly(1))->method('isStarted')->willReturn(true);
49+
50+
if (isset($phpSessionOptions['samesite'])) {
51+
ini_set('session.cookie_samesite', $phpSessionOptions['samesite']);
52+
}
53+
session_set_cookie_params(0, $phpSessionOptions['path'] ?? null, $phpSessionOptions['domain'] ?? null, $phpSessionOptions['secure'] ?? null, $phpSessionOptions['httponly'] ?? null);
54+
55+
$container = new Container();
56+
$container->set('initialized_session', $session);
57+
58+
$listener = new SessionListener($container, false, $sessionOptions);
59+
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->disableOriginalConstructor()->getMock();
60+
61+
$request = new Request();
62+
$listener->onKernelRequest(new RequestEvent($kernel, $request, HttpKernelInterface::MAIN_REQUEST));
63+
64+
$response = new Response();
65+
$listener->onKernelResponse(new ResponseEvent($kernel, new Request(), HttpKernelInterface::MAIN_REQUEST, $response));
66+
67+
$cookies = $response->headers->getCookies();
68+
$this->assertSame('PHPSESSID', $cookies[0]->getName());
69+
$this->assertSame('123456', $cookies[0]->getValue());
70+
$this->assertSame($expectedSessionOptions['cookie_path'], $cookies[0]->getPath());
71+
$this->assertSame($expectedSessionOptions['cookie_domain'], $cookies[0]->getDomain());
72+
$this->assertSame($expectedSessionOptions['cookie_secure'], $cookies[0]->isSecure());
73+
$this->assertSame($expectedSessionOptions['cookie_httponly'], $cookies[0]->isHttpOnly());
74+
$this->assertSame($expectedSessionOptions['cookie_samesite'], $cookies[0]->getSameSite());
75+
}
76+
77+
public function provideSessionOptions(): \Generator
78+
{
79+
if (\PHP_VERSION_ID > 70300) {
80+
yield 'set_samesite_by_php' => [
81+
'phpSessionOptions' => ['samesite' => Cookie::SAMESITE_STRICT],
82+
'sessionOptions' => ['cookie_path' => '/test/', 'cookie_domain' => '', 'cookie_secure' => true, 'cookie_httponly' => true],
83+
'expectedSessionOptions' => ['cookie_path' => '/test/', 'cookie_domain' => '', 'cookie_secure' => true, 'cookie_httponly' => true, 'cookie_samesite' => Cookie::SAMESITE_STRICT],
84+
];
85+
}
86+
87+
yield 'set_cookie_path_by_php' => [
88+
'phpSessionOptions' => ['path' => '/prod/'],
89+
'sessionOptions' => ['cookie_domain' => '', 'cookie_secure' => true, 'cookie_httponly' => true, 'cookie_samesite' => Cookie::SAMESITE_LAX],
90+
'expectedSessionOptions' => ['cookie_path' => '/prod/', 'cookie_domain' => '', 'cookie_secure' => true, 'cookie_httponly' => true, 'cookie_samesite' => Cookie::SAMESITE_LAX],
91+
];
92+
93+
yield 'set_cookie_secure_by_php' => [
94+
'phpSessionOptions' => ['secure' => true],
95+
'sessionOptions' => ['cookie_path' => '/test/', 'cookie_domain' => '', 'cookie_httponly' => true, 'cookie_samesite' => Cookie::SAMESITE_LAX],
96+
'expectedSessionOptions' => ['cookie_path' => '/test/', 'cookie_domain' => '', 'cookie_secure' => true, 'cookie_httponly' => true, 'cookie_samesite' => Cookie::SAMESITE_LAX],
97+
];
98+
99+
yield 'set_cookiesecure_auto_by_symfony_false_by_php' => [
100+
'phpSessionOptions' => ['secure' => false],
101+
'sessionOptions' => ['cookie_path' => '/test/', 'cookie_httponly' => 'auto', 'cookie_secure' => 'auto', 'cookie_samesite' => Cookie::SAMESITE_LAX],
102+
'expectedSessionOptions' => ['cookie_path' => '/test/', 'cookie_domain' => '', 'cookie_secure' => false, 'cookie_httponly' => true, 'cookie_samesite' => Cookie::SAMESITE_LAX],
103+
];
104+
105+
yield 'set_cookiesecure_auto_by_symfony_true_by_php' => [
106+
'phpSessionOptions' => ['secure' => true],
107+
'sessionOptions' => ['cookie_path' => '/test/', 'cookie_httponly' => 'auto', 'cookie_secure' => 'auto', 'cookie_samesite' => Cookie::SAMESITE_LAX],
108+
'expectedSessionOptions' => ['cookie_path' => '/test/', 'cookie_domain' => '', 'cookie_secure' => true, 'cookie_httponly' => true, 'cookie_samesite' => Cookie::SAMESITE_LAX],
109+
];
110+
111+
yield 'set_cookie_httponly_by_php' => [
112+
'phpSessionOptions' => ['httponly' => true],
113+
'sessionOptions' => ['cookie_path' => '/test/', 'cookie_domain' => '', 'cookie_secure' => true, 'cookie_samesite' => Cookie::SAMESITE_LAX],
114+
'expectedSessionOptions' => ['cookie_path' => '/test/', 'cookie_domain' => '', 'cookie_secure' => true, 'cookie_httponly' => true, 'cookie_samesite' => Cookie::SAMESITE_LAX],
115+
];
116+
117+
yield 'set_cookie_domain_by_php' => [
118+
'phpSessionOptions' => ['domain' => 'test.symfony'],
119+
'sessionOptions' => ['cookie_path' => '/test/', 'cookie_httponly' => true, 'cookie_secure' => true, 'cookie_samesite' => Cookie::SAMESITE_LAX],
120+
'expectedSessionOptions' => ['cookie_path' => '/test/', 'cookie_domain' => 'test.symfony', 'cookie_secure' => true, 'cookie_httponly' => true, 'cookie_samesite' => Cookie::SAMESITE_LAX],
121+
];
122+
123+
yield 'set_samesite_by_symfony' => [
124+
'phpSessionOptions' => ['samesite' => Cookie::SAMESITE_STRICT],
125+
'sessionOptions' => ['cookie_path' => '/test/', 'cookie_httponly' => true, 'cookie_secure' => true, 'cookie_samesite' => Cookie::SAMESITE_LAX],
126+
'expectedSessionOptions' => ['cookie_path' => '/test/', 'cookie_domain' => '', 'cookie_secure' => true, 'cookie_httponly' => true, 'cookie_samesite' => Cookie::SAMESITE_LAX],
127+
];
128+
}
129+
36130
public function testOnlyTriggeredOnMainRequest()
37131
{
38132
$listener = $this->getMockForAbstractClass(AbstractSessionListener::class);
@@ -160,10 +254,10 @@ public function testSessionSaveAndResponseHasSessionCookie()
160254
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->disableOriginalConstructor()->getMock();
161255

162256
$request = new Request();
163-
$listener->onKernelRequest(new RequestEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST));
257+
$listener->onKernelRequest(new RequestEvent($kernel, $request, HttpKernelInterface::MAIN_REQUEST));
164258

165259
$response = new Response();
166-
$listener->onKernelResponse(new ResponseEvent($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, $response));
260+
$listener->onKernelResponse(new ResponseEvent($kernel, new Request(), HttpKernelInterface::MAIN_REQUEST, $response));
167261

168262
$cookies = $response->headers->getCookies();
169263
$this->assertSame('PHPSESSID', $cookies[0]->getName());

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.