Skip to content

Commit be4275a

Browse files
committed
Session: security options can not be bypassed
1 parent 34946ca commit be4275a

File tree

3 files changed

+15
-39
lines changed

3 files changed

+15
-39
lines changed

src/Http/Session.php

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ class Session
2222
/** Default file lifetime */
2323
private const DEFAULT_FILE_LIFETIME = 3 * Nette\Utils\DateTime::HOUR;
2424

25+
/** @var array default configuration */
26+
private const SECURITY_OPTIONS = [
27+
'referer_check' => '', // must be disabled because PHP implementation is invalid
28+
'use_cookies' => 1, // must be enabled to prevent Session Hijacking and Fixation
29+
'use_only_cookies' => 1, // must be enabled to prevent Session Fixation
30+
'use_trans_sid' => 0, // must be disabled to prevent Session Hijacking and Fixation
31+
'use_strict_mode' => 1, // must be enabled to prevent Session Fixation
32+
'cookie_httponly' => true, // must be enabled to prevent Session Hijacking
33+
];
34+
2535
/** @var bool has been session ID regenerated? */
2636
private $regenerated = false;
2737

@@ -30,18 +40,7 @@ class Session
3040

3141
/** @var array default configuration */
3242
private $options = [
33-
// security
34-
'referer_check' => '', // must be disabled because PHP implementation is invalid
35-
'use_cookies' => 1, // must be enabled to prevent Session Hijacking and Fixation
36-
'use_only_cookies' => 1, // must be enabled to prevent Session Fixation
37-
'use_trans_sid' => 0, // must be disabled to prevent Session Hijacking and Fixation
38-
'use_strict_mode' => 1, // must be enabled to prevent Session Fixation
39-
40-
// cookies
4143
'cookie_lifetime' => 0, // until the browser is closed
42-
'cookie_httponly' => true, // must be enabled to prevent Session Hijacking
43-
44-
// other
4544
'gc_maxlifetime' => self::DEFAULT_FILE_LIFETIME, // 3 hours
4645
];
4746

@@ -73,19 +72,20 @@ public function start(): void
7372
{
7473
if (session_status() === PHP_SESSION_ACTIVE) {
7574
if (!$this->started) {
75+
$this->configure(self::SECURITY_OPTIONS);
7676
$this->initialize();
7777
}
7878
return;
7979
}
8080

81-
$this->configure($this->options);
81+
$this->configure(self::SECURITY_OPTIONS + $this->options);
8282

83-
if (!session_id()) {
83+
if (!session_id()) { // session is started for first time
8484
$id = $this->request->getCookie(session_name());
8585
$id = is_string($id) && preg_match('#^[0-9a-zA-Z,-]{22,256}\z#i', $id)
8686
? $id
8787
: session_create_id();
88-
session_id($id);
88+
session_id($id); // causes resend of a cookie
8989
}
9090

9191
try {
@@ -123,7 +123,7 @@ private function initialize(): void
123123
// regenerate empty session
124124
if (empty($nf['Time'])) {
125125
$nf['Time'] = time();
126-
$this->regenerateId();
126+
$this->regenerateId(); // ensures that the session was created in strict mode (see use_strict_mode)
127127
}
128128

129129
// process meta metadata

tests/Http/Session.cookies.phpt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,7 @@ $response->cookieDomain = 'nette.org';
1919
$response->cookieSecure = true;
2020

2121
Assert::same([
22-
'referer_check' => '',
23-
'use_cookies' => 1,
24-
'use_only_cookies' => 1,
25-
'use_trans_sid' => 0,
26-
'use_strict_mode' => 1,
2722
'cookie_lifetime' => 0,
28-
'cookie_httponly' => true,
2923
'gc_maxlifetime' => 10800,
3024
'cookie_path' => '/user/',
3125
'cookie_domain' => 'nette.org',

tests/Http/Session.setOptions.phpt

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,7 @@ $factory = new Nette\Http\RequestFactory;
1616
$session = new Nette\Http\Session($factory->createHttpRequest(), new Nette\Http\Response);
1717

1818
Assert::same([
19-
'referer_check' => '',
20-
'use_cookies' => 1,
21-
'use_only_cookies' => 1,
22-
'use_trans_sid' => 0,
23-
'use_strict_mode' => 1,
2419
'cookie_lifetime' => 0,
25-
'cookie_httponly' => true,
2620
'gc_maxlifetime' => 10800,
2721
'cookie_path' => '/',
2822
'cookie_domain' => '',
@@ -34,13 +28,7 @@ $session->setOptions([
3428
]);
3529
Assert::same([
3630
'cookie_domain' => '.domain.com',
37-
'referer_check' => '',
38-
'use_cookies' => 1,
39-
'use_only_cookies' => 1,
40-
'use_trans_sid' => 0,
41-
'use_strict_mode' => 1,
4231
'cookie_lifetime' => 0,
43-
'cookie_httponly' => true,
4432
'gc_maxlifetime' => 10800,
4533
'cookie_path' => '/',
4634
'cookie_secure' => false,
@@ -51,13 +39,7 @@ $session->setOptions([
5139
]);
5240
Assert::same([
5341
'cookie_domain' => '.domain.org',
54-
'referer_check' => '',
55-
'use_cookies' => 1,
56-
'use_only_cookies' => 1,
57-
'use_trans_sid' => 0,
58-
'use_strict_mode' => 1,
5942
'cookie_lifetime' => 0,
60-
'cookie_httponly' => true,
6143
'gc_maxlifetime' => 10800,
6244
'cookie_path' => '/',
6345
'cookie_secure' => false,

0 commit comments

Comments
 (0)