reference/session/functions/session-regenerate-id.xml
a0ae28d3bc85f927c22649ebd9a590b921534b7d
...
...
@@ -12,7 +12,7 @@
12
12
&reftitle.description;
13
13
<methodsynopsis>
14
14
<type>bool</type><methodname>session_regenerate_id</methodname>
15
-
<methodparam choice="opt"><type>bool</type><parameter>delete_old_session</parameter><initializer>false</initializer></methodparam>
15
+
<methodparam choice="opt"><type>bool</type><parameter>delete_old_session</parameter><initializer>&false;</initializer></methodparam>
16
16
</methodsynopsis>
17
17
<para>
18
18
<function>session_regenerate_id</function> will replace the current
...
...
@@ -23,6 +23,22 @@
23
23
is enabled, output must be started after <function>session_regenerate_id</function>
24
24
call. Otherwise, old session ID is used.
25
25
</para>
26
+
<warning>
27
+
<para>
28
+
Currently, session_regenerate_id does not handle an unstable network well,
29
+
e.g. Mobile and WiFi network. Therefore, you may experience a lost
30
+
session by calling session_regenerate_id.
31
+
</para>
32
+
<para>
33
+
You should not destroy old session data immediately, but should use
34
+
destroy time-stamp and control access to old session ID. Otherwise,
35
+
concurrent access to page may result in inconsistent state, or you
36
+
may have lost session, or it may cause client(browser) side race
37
+
condition and may create many session ID needlessly. Immediate
38
+
session data deletion disables session hijack attack detection
39
+
and prevention also.
40
+
</para>
41
+
</warning>
26
42
</refsect1>
27
43

28
44
<refsect1 role="parameters">
...
...
@@ -34,6 +50,9 @@
34
50
<listitem>
35
51
<para>
36
52
Whether to delete the old associated session file or not.
53
+
You should not delete old session if you need to avoid
54
+
races caused by deletion or detect/avoid session hijack
55
+
attacks.
37
56
</para>
38
57
</listitem>
39
58
</varlistentry>
...
...
@@ -48,38 +67,6 @@
48
67
</para>
49
68
</refsect1>
50
69

51
-
<refsect1 role="changelog">
52
-
&reftitle.changelog;
53
-
<para>
54
-
<informaltable>
55
-
<tgroup cols="2">
56
-
<thead>
57
-
<row>
58
-
<entry>&Version;</entry>
59
-
<entry>&Description;</entry>
60
-
</row>
61
-
</thead>
62
-
<tbody>
63
-
<row>
64
-
<entry>4.3.3</entry>
65
-
<entry>
66
-
Since then, if session cookies are enabled, use of
67
-
<function>session_regenerate_id</function> will also submit a new
68
-
session cookie with the new session id.
69
-
</entry>
70
-
</row>
71
-
<row>
72
-
<entry>5.1.0</entry>
73
-
<entry>
74
-
Added the <parameter>delete_old_session</parameter> parameter.
75
-
</entry>
76
-
</row>
77
-
</tbody>
78
-
</tgroup>
79
-
</informaltable>
80
-
</para>
81
-
</refsect1>
82
-

83
70
<refsect1 role="examples">
84
71
&reftitle.examples;
85
72
<para>
...
...
@@ -88,12 +75,31 @@
88
75
<programlisting role="php">
89
76
<![CDATA[
90
77
<?php
78
+
// NOTE: This code is not fully working code, but an example!
79
+

91
80
session_start();
92
81

82
+
// Check destroyed time-stamp
83
+
if (isset($_SESSION['destroyed'])
84
+
&& $_SESSION['destroyed'] < time() - 300) {
85
+
// Should not happen usually. This could be attack or due to unstable network.
86
+
// Remove all authentication status of this users session.
87
+
remove_all_authentication_flag_from_active_sessions($_SESSION['userid']);
88
+
throw(new DestroyedSessionAccessException);
89
+
}
90
+

93
91
$old_sessionid = session_id();
94
92

93
+
// Set destroyed timestamp
94
+
$_SESSION['destroyed'] = time(); // session_regenerate_id() saves old session data
95
+

96
+
// Simply calling session_regenerate_id() may result in lost session, etc.
97
+
// See next example.
95
98
session_regenerate_id();
96
99

100
+
// New session does not need destroyed timestamp
101
+
unset($_SESSION['destroyed']);
102
+

97
103
$new_sessionid = session_id();
98
104

99
105
echo "Old Session: $old_sessionid<br />";
...
...
@@ -105,6 +111,74 @@ print_r($_SESSION);
105
111
</programlisting>
106
112
</example>
107
113
</para>
114
+

115
+
<para>
116
+
Current session module does not handle unstable network well. You should
117
+
manage session ID to avoid lost session by session_regenerate_id.
118
+
</para>
119
+

120
+
<para>
121
+
<example>
122
+
<title>Avoiding lost session by <function>session_regenerate_id</function></title>
123
+
<programlisting role="php">
124
+
<![CDATA[
125
+
<?php
126
+
// NOTE: This code is not fully working code, but an example!
127
+
// my_session_start() and my_session_regenerate_id() avoid lost sessions by
128
+
// unstable network. In addition, this code may prevent exploiting stolen
129
+
// session by attackers.
130
+

131
+
function my_session_start() {
132
+
session_start();
133
+
if (isset($_SESSION['destroyed'])) {
134
+
if ($_SESSION['destroyed'] < time()-300) {
135
+
// Should not happen usually. This could be attack or due to unstable network.
136
+
// Remove all authentication status of this users session.
137
+
remove_all_authentication_flag_from_active_sessions($_SESSION['userid']);
138
+
throw(new DestroyedSessionAccessException);
139
+
}
140
+
if (isset($_SESSION['new_session_id'])) {
141
+
// Not fully expired yet. Could be lost cookie by unstable network.
142
+
// Try again to set proper session ID cookie.
143
+
// NOTE: Do not try to set session ID again if you would like to remove
144
+
// authentication flag.
145
+
session_commit();
146
+
session_id($_SESSION['new_session_id']);
147
+
// New session ID should exist
148
+
session_start();
149
+
return;
150
+
}
151
+
}
152
+
}
153
+

154
+
function my_session_regenerate_id() {
155
+
// New session ID is required to set proper session ID
156
+
// when session ID is not set due to unstable network.
157
+
$new_session_id = session_create_id();
158
+
$_SESSION['new_session_id'] = $new_session_id;
159
+
160
+
// Set destroy timestamp
161
+
$_SESSION['destroyed'] = time();
162
+
163
+
// Write and close current session;
164
+
session_commit();
165
+

166
+
// Start session with new session ID
167
+
session_id($new_session_id);
168
+
ini_set('session.use_strict_mode', 0);
169
+
session_start();
170
+
ini_set('session.use_strict_mode', 1);
171
+
172
+
// New session does not need them
173
+
unset($_SESSION['destroyed']);
174
+
unset($_SESSION['new_session_id']);
175
+
}
176
+
?>
177
+
]]>
178
+
</programlisting>
179
+
</example>
180
+
</para>
181
+

108
182
</refsect1>
109
183

110
184
<refsect1 role="seealso">
...
...
@@ -112,7 +186,10 @@ print_r($_SESSION);
112
186
<para>
113
187
<simplelist>
114
188
<member><function>session_id</function></member>
189
+
<member><function>session_create_id</function></member>
115
190
<member><function>session_start</function></member>
191
+
<member><function>session_destroy</function></member>
192
+
<member><function>session_reset</function></member>
116
193
<member><function>session_name</function></member>
117
194
</simplelist>
118
195
</para>
119
196