summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Fuhrmannek2016-03-07 23:29:21 +0100
committerBen Fuhrmannek2016-03-07 23:29:21 +0100
commita17a53b490bd5127a7ec67063a31b186e6956805 (patch)
treef64e5e866940e47b6c054f4bbf9fa342377a7517
parentf2788a5543f72cdbe5fafd95ea7b37fab06745e3 (diff)
session support
-rw-r--r--config.m42
-rw-r--r--cookiecrypt.c5
-rw-r--r--header.c2
-rw-r--r--php_suhosin7.h16
-rw-r--r--session.c309
-rw-r--r--suhosin7.c16
-rw-r--r--tests/session/PHPSESSID_max_id_length_ok.phpt16
-rw-r--r--tests/session/PHPSESSID_max_id_length_toolong.phpt16
-rw-r--r--tests/session/crypt.checkraddr_4.phpt29
-rw-r--r--tests/session/crypt.checkraddr_4_incorrect.phpt27
-rw-r--r--tests/session/crypt.docroot.phpt25
-rw-r--r--tests/session/crypt.key_default.phpt21
-rw-r--r--tests/session/crypt.key_empty.phpt21
-rw-r--r--tests/session/crypt.key_empty_remote_addr.phpt25
-rw-r--r--tests/session/crypt.no_encryption.phpt15
-rw-r--r--tests/session/crypt.raddr_1.phpt25
-rw-r--r--tests/session/crypt.raddr_2.phpt25
-rw-r--r--tests/session/crypt.raddr_3.phpt25
-rw-r--r--tests/session/crypt.raddr_4.phpt25
-rw-r--r--tests/session/crypt.ua.phpt25
-rw-r--r--tests/session/max_id_length_ok.phpt16
-rw-r--r--tests/session/max_id_length_toolong.phpt15
-rw-r--r--tests/session/session_recursive_crash.phpt25
-rw-r--r--tests/session/session_recursive_crash2.phpt61
-rw-r--r--tests/session/sessionhandler.inc43
25 files changed, 819 insertions, 11 deletions
diff --git a/config.m4 b/config.m4
index 9cb8969..a6dade9 100644
--- a/config.m4
+++ b/config.m4
@@ -5,7 +5,7 @@ PHP_ARG_ENABLE(suhosin7, whether to enable suhosin support,
5[ --enable-suhosin7 Enable suhosin support]) 5[ --enable-suhosin7 Enable suhosin support])
6 6
7if test "$PHP_SUHOSIN7" != "no"; then 7if test "$PHP_SUHOSIN7" != "no"; then
8 PHP_NEW_EXTENSION(suhosin7, suhosin7.c ifilter.c memory_limit.c aes.c treat_data.c log.c execute.c execute_ih.c execute_rnd.c crypt.c cookiecrypt.c header.c, $ext_shared,, [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) 8 PHP_NEW_EXTENSION(suhosin7, suhosin7.c ifilter.c memory_limit.c aes.c treat_data.c log.c execute.c execute_ih.c execute_rnd.c crypt.c cookiecrypt.c header.c session.c, $ext_shared,, [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1])
9 PHP_ADD_EXTENSION_DEP(suhosin7, hash) 9 PHP_ADD_EXTENSION_DEP(suhosin7, hash)
10 echo "===== WARNING ============================================" 10 echo "===== WARNING ============================================"
11 echo " Suhosin7 for PHP 7 is in alpha stage at the moment and" 11 echo " Suhosin7 for PHP 7 is in alpha stage at the moment and"
diff --git a/cookiecrypt.c b/cookiecrypt.c
index 70b0c5a..f4f3638 100644
--- a/cookiecrypt.c
+++ b/cookiecrypt.c
@@ -106,8 +106,9 @@ char *suhosin_cookie_decryptor(char *raw_cookie)
106 // int j; 106 // int j;
107 char cryptkey[33]; 107 char cryptkey[33];
108 108
109 suhosin_generate_key(SUHOSIN7_G(cookie_cryptkey), SUHOSIN7_G(cookie_cryptua), SUHOSIN7_G(cookie_cryptdocroot), SUHOSIN7_G(cookie_cryptraddr), cryptkey); 109 // suhosin_generate_key(SUHOSIN7_G(cookie_cryptkey), SUHOSIN7_G(cookie_cryptua), SUHOSIN7_G(cookie_cryptdocroot), SUHOSIN7_G(cookie_cryptraddr), cryptkey);
110 SDEBUG("cryptkey=%02x.%02x.%02x", cryptkey[0], cryptkey[1], cryptkey[2]); 110 S7_GENERATE_KEY(cookie, cryptkey);
111 // SDEBUG("cryptkey=%02x.%02x.%02x", cryptkey[0], cryptkey[1], cryptkey[2]);
111 112
112 ret = decrypted = emalloc(strlen(raw_cookie)*4+1); 113 ret = decrypted = emalloc(strlen(raw_cookie)*4+1);
113 raw_cookie = estrdup(raw_cookie); 114 raw_cookie = estrdup(raw_cookie);
diff --git a/header.c b/header.c
index a916746..b7ce010 100644
--- a/header.c
+++ b/header.c
@@ -75,7 +75,7 @@ static int suhosin_header_handler(sapi_header_struct *sapi_header, sapi_header_o
75 int nlen, vlen, len, tlen; 75 int nlen, vlen, len, tlen;
76 char cryptkey[33]; 76 char cryptkey[33];
77 77
78 suhosin_generate_key(SUHOSIN7_G(cookie_cryptkey), SUHOSIN7_G(cookie_cryptua), SUHOSIN7_G(cookie_cryptdocroot), SUHOSIN7_G(cookie_cryptraddr), (char *)cryptkey); 78 S7_GENERATE_KEY(cookie, cryptkey);
79 start = estrndup(sapi_header->header, sapi_header->header_len); 79 start = estrndup(sapi_header->header, sapi_header->header_len);
80 rend = end = start + sapi_header->header_len; 80 rend = end = start + sapi_header->header_len;
81 81
diff --git a/php_suhosin7.h b/php_suhosin7.h
index cbde402..75244fe 100644
--- a/php_suhosin7.h
+++ b/php_suhosin7.h
@@ -71,6 +71,9 @@ extern zend_module_entry suhosin7_module_entry;
71// PHP_MINFO_FUNCTION(suhosin); 71// PHP_MINFO_FUNCTION(suhosin);
72 72
73#include "ext/standard/basic_functions.h" 73#include "ext/standard/basic_functions.h"
74#ifdef HAVE_PHP_SESSION
75#include "ext/session/php_session.h"
76#endif
74 77
75static inline int suhosin_is_protected_varname(char *var, int var_len) 78static inline int suhosin_is_protected_varname(char *var, int var_len)
76{ 79{
@@ -219,6 +222,15 @@ ZEND_BEGIN_MODULE_GLOBALS(suhosin7)
219 zend_bool no_more_cookie_variables; 222 zend_bool no_more_cookie_variables;
220 zend_bool no_more_uploads; 223 zend_bool no_more_uploads;
221 224
225 /* session */
226#ifdef HAVE_PHP_SESSION
227 void *s_module;
228 void *s_original_mod;
229 int (*old_s_read)(PS_READ_ARGS);
230 int (*old_s_write)(PS_WRITE_ARGS);
231 int (*old_s_destroy)(PS_DESTROY_ARGS);
232#endif
233
222 /* encryption */ 234 /* encryption */
223 BYTE fi[24],ri[24]; 235 BYTE fi[24],ri[24];
224 WORD fkey[120]; 236 WORD fkey[120];
@@ -377,6 +389,9 @@ void suhosin_hook_header_handler();
377void suhosin_unhook_header_handler(); 389void suhosin_unhook_header_handler();
378void suhosin_hook_execute(); 390void suhosin_hook_execute();
379// void suhosin_hook_sha256(); 391// void suhosin_hook_sha256();
392#ifdef HAVE_PHP_SESSION
393void suhosin_hook_session();
394#endif
380 395
381// ifilter.c 396// ifilter.c
382void suhosin_normalize_varname(char *varname); 397void suhosin_normalize_varname(char *varname);
@@ -390,6 +405,7 @@ char *suhosin_decrypt_single_cookie(char *name, int name_len, char *value, int v
390zend_string *suhosin_encrypt_string(char *str, int len, char *var, int vlen, char *key); 405zend_string *suhosin_encrypt_string(char *str, int len, char *var, int vlen, char *key);
391zend_string *suhosin_decrypt_string(char *str, int padded_len, char *var, int vlen, char *key, int check_ra); 406zend_string *suhosin_decrypt_string(char *str, int padded_len, char *var, int vlen, char *key, int check_ra);
392char *suhosin_generate_key(char *key, zend_bool ua, zend_bool dr, long raddr, char *cryptkey); 407char *suhosin_generate_key(char *key, zend_bool ua, zend_bool dr, long raddr, char *cryptkey);
408#define S7_GENERATE_KEY(type, keyvar) suhosin_generate_key(SUHOSIN7_G(type ## _cryptkey), SUHOSIN7_G(type ## _cryptua), SUHOSIN7_G(type ## _cryptdocroot), SUHOSIN7_G(type ## _cryptraddr), (char *)keyvar);
393 409
394// aes.c 410// aes.c
395void suhosin_aes_gentables(); 411void suhosin_aes_gentables();
diff --git a/session.c b/session.c
new file mode 100644
index 0000000..ad114d4
--- /dev/null
+++ b/session.c
@@ -0,0 +1,309 @@
1/*
2 +----------------------------------------------------------------------+
3 | Suhosin Version 1 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2006-2007 The Hardened-PHP Project |
6 | Copyright (c) 2007-2016 SektionEins GmbH |
7 +----------------------------------------------------------------------+
8 | This source file is subject to version 3.01 of the PHP license, |
9 | that is bundled with this package in the file LICENSE, and is |
10 | available through the world-wide-web at the following url: |
11 | http://www.php.net/license/3_01.txt |
12 | If you did not receive a copy of the PHP license and are unable to |
13 | obtain it through the world-wide-web, please send a note to |
14 | license@php.net so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+
16 | Authors: Stefan Esser <sesser@sektioneins.de> |
17 | Ben Fuhrmannek <ben.fuhrmannek@sektioneins.de> |
18 +----------------------------------------------------------------------+
19*/
20/*
21 $Id: session.c,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $
22*/
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include "php.h"
29#include "SAPI.h"
30#include "php_ini.h"
31#include "zend_smart_str.h"
32#include "ext/standard/php_var.h"
33#include <fcntl.h>
34
35#include "php_suhosin7.h"
36
37#include "ext/hash/php_hash.h"
38
39#ifdef HAVE_PHP_SESSION
40#include "ext/session/php_session.h"
41
42#ifdef ZTS
43static ts_rsrc_id session_globals_id = 0;
44#define SESSION_G(v) ZEND_TSRMG(session_globals_id, php_ps_globals *, v)
45# ifdef COMPILE_DL_SESSION
46ZEND_TSRMLS_CACHE_EXTERN();
47# endif
48#else
49static php_ps_globals *session_globals = NULL;
50#define SESSION_G(v) (ps_globals.v)
51#endif
52
53#define COND_DUMB_SH key == NULL || ZSTR_LEN(key) == 0 || ZSTR_VAL(key)[0] == 0 \
54 || ZSTR_LEN(key) > SUHOSIN7_G(session_max_id_length) \
55 || ((mod_data == NULL || *mod_data == NULL) && !SESSION_G(mod_user_implemented))
56
57static void suhosin_send_cookie()
58{
59 int * session_send_cookie = &SESSION_G(send_cookie);
60 char * base;
61 zend_ini_entry *ini_entry;
62
63 /* The following is requires to be 100% compatible to PHP
64 versions where the hash extension is not available by default */
65 if ((ini_entry = zend_hash_str_find_ptr(EG(ini_directives), ZEND_STRL("session.hash_bits_per_character"))) != NULL) {
66#ifndef ZTS
67 base = (char *) ini_entry->mh_arg2;
68#else
69 base = (char *) ts_resource(*((int *) ini_entry->mh_arg2));
70#endif
71 session_send_cookie = (int *) (base+(size_t) ini_entry->mh_arg1+sizeof(long));
72 }
73 *session_send_cookie = 1;
74}
75
76
77
78static ZEND_INI_MH((*old_OnUpdateSaveHandler)) = NULL;
79static int (*old_SessionRINIT)(INIT_FUNC_ARGS) = NULL;
80
81static int suhosin_hook_s_read(PS_READ_ARGS)
82{
83 zend_string *new_key = key;
84
85 /* protect session vars */
86/* if (SESSION_G(http_session_vars) && SESSION_G(http_session_vars)->type == IS_ARRAY) {
87 SESSION_G(http_session_vars)->refcount++;
88 }*/
89
90 /* protect dumb session handlers */
91 if (COND_DUMB_SH) {
92regenerate:
93 SDEBUG("regenerating key. old key was %s", key ? ZSTR_VAL(key) : "<NULL>");
94 zend_string_release(SESSION_G(id));
95 new_key = SESSION_G(id) = SESSION_G(mod)->s_create_sid(&SESSION_G(mod_data));
96 suhosin_send_cookie();
97 } else if (ZSTR_LEN(key) > SUHOSIN7_G(session_max_id_length)) {
98 suhosin_log(S_SESSION, "session id ('%s') exceeds maximum length - regenerating", ZSTR_VAL(key));
99 if (!SUHOSIN7_G(simulation)) {
100 goto regenerate;
101 }
102 }
103
104 int r = SUHOSIN7_G(old_s_read)(mod_data, new_key, val, maxlifetime);
105
106 if (r == SUCCESS && SUHOSIN7_G(session_encrypt) && val != NULL && *val != NULL && ZSTR_LEN(*val)) {
107 char cryptkey[33];
108
109 // SUHOSIN7_G(do_not_scan) = 1;
110 S7_GENERATE_KEY(session, cryptkey);
111
112 zend_string *orig_val = *val;
113 *val = suhosin_decrypt_string(ZSTR_VAL(*val), ZSTR_LEN(*val), "", 0, (char *)cryptkey, SUHOSIN7_G(session_checkraddr));
114 // SUHOSIN7_G(do_not_scan) = 0;
115 if (*val == NULL) {
116 *val = ZSTR_EMPTY_ALLOC();
117 }
118 zend_string_release(orig_val);
119 }
120
121 return r;
122}
123
124static int suhosin_hook_s_write(PS_WRITE_ARGS)
125{
126 /* protect dumb session handlers */
127 if (COND_DUMB_SH) {
128 return FAILURE;
129 }
130
131 if (ZSTR_LEN(val) > 0 && SUHOSIN7_G(session_encrypt)) {
132 char cryptkey[33];
133 // SUHOSIN7_G(do_not_scan) = 1;
134 S7_GENERATE_KEY(session, cryptkey);
135
136 zend_string *v = suhosin_encrypt_string(ZSTR_VAL(val), ZSTR_LEN(val), "", 0, cryptkey);
137
138 // SUHOSIN7_G(do_not_scan) = 0;
139 return SUHOSIN7_G(old_s_write)(mod_data, key, v, maxlifetime);
140 }
141
142 return SUHOSIN7_G(old_s_write)(mod_data, key, val, maxlifetime);
143
144// return_write:
145 /* protect session vars */
146/* if (SESSION_G(http_session_vars) && SESSION_G(http_session_vars)->type == IS_ARRAY) {
147 if (SESSION_G(http_session_vars)->refcount==1) {
148 nullify = 1;
149 }
150 zval_ptr_dtor(&SESSION_G(http_session_vars));
151 if (nullify) {
152 suhosin_log(S_SESSION, "possible session variables double free attack stopped");
153 SESSION_G(http_session_vars) = NULL;
154 }
155 }*/
156
157 // return r;
158}
159
160static int suhosin_hook_s_destroy(PS_DESTROY_ARGS)
161{
162 /* protect dumb session handlers */
163 if (COND_DUMB_SH) {
164 return FAILURE;
165 }
166
167 return SUHOSIN7_G(old_s_destroy)(mod_data, key);
168}
169
170static void suhosin_hook_session_module()
171{
172 ps_module *old_mod = SESSION_G(mod);
173 ps_module *mod;
174
175 if (old_mod == NULL || SUHOSIN7_G(s_module) == old_mod) {
176 return;
177 }
178
179 if (SUHOSIN7_G(s_module) == NULL) {
180 SUHOSIN7_G(s_module) = mod = malloc(sizeof(ps_module));
181 if (mod == NULL) {
182 return;
183 }
184 }
185
186 SUHOSIN7_G(s_original_mod) = old_mod;
187
188 mod = SUHOSIN7_G(s_module);
189 memcpy(mod, old_mod, sizeof(ps_module));
190
191 SUHOSIN7_G(old_s_read) = mod->s_read;
192 mod->s_read = suhosin_hook_s_read;
193 SUHOSIN7_G(old_s_write) = mod->s_write;
194 mod->s_write = suhosin_hook_s_write;
195 SUHOSIN7_G(old_s_destroy) = mod->s_destroy;
196 mod->s_destroy = suhosin_hook_s_destroy;
197
198 SESSION_G(mod) = mod;
199}
200
201static PHP_INI_MH(suhosin_OnUpdateSaveHandler)
202{
203 if (stage == PHP_INI_STAGE_RUNTIME
204 && SESSION_G(session_status) == php_session_none
205 && SUHOSIN7_G(s_original_mod)
206 && zend_string_equals_literal(new_value, "user") == 0
207 && strcmp(((ps_module*)SUHOSIN7_G(s_original_mod))->s_name, "user") == 0) {
208 return SUCCESS;
209 }
210
211 SESSION_G(mod) = SUHOSIN7_G(s_original_mod);
212
213 int r = old_OnUpdateSaveHandler(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
214
215 suhosin_hook_session_module();
216
217 return r;
218}
219
220
221static int suhosin_hook_session_RINIT(INIT_FUNC_ARGS)
222{
223 if (SESSION_G(mod) == NULL) {
224 zend_ini_entry *ini_entry;
225 if ((ini_entry = zend_hash_str_find_ptr(EG(ini_directives), ZEND_STRL("session.save_handler")))) {
226 if (ini_entry->value) {
227 suhosin_OnUpdateSaveHandler(NULL, ini_entry->value, NULL, NULL, NULL, 0);
228 }
229 }
230 }
231 return old_SessionRINIT(INIT_FUNC_ARGS_PASSTHRU);
232}
233
234void suhosin_hook_session()
235{
236 zend_module_entry *module;
237
238 if ((module = zend_hash_str_find_ptr(&module_registry, ZEND_STRL("session"))) == NULL) {
239 return;
240 }
241 /* retrieve globals from module entry struct if possible */
242#ifdef ZTS
243 if (session_globals_id == 0) {
244 session_globals_id = *module->globals_id_ptr;
245 }
246#else
247 if (session_globals == NULL) {
248 session_globals = module->globals_ptr;
249 }
250#endif
251
252 if (old_OnUpdateSaveHandler != NULL) {
253 return;
254 }
255
256 /* hook request startup function of session module */
257 old_SessionRINIT = module->request_startup_func;
258 module->request_startup_func = suhosin_hook_session_RINIT;
259
260 /* retrieve pointer to session.save_handler ini entry */
261 zend_ini_entry *ini_entry;
262 if ((ini_entry = zend_hash_str_find_ptr(EG(ini_directives), ZEND_STRL("session.save_handler"))) != NULL) {
263 /* replace OnUpdateMemoryLimit handler */
264 old_OnUpdateSaveHandler = ini_entry->on_modify;
265 ini_entry->on_modify = suhosin_OnUpdateSaveHandler;
266 }
267 SUHOSIN7_G(s_module) = NULL;
268
269 suhosin_hook_session_module();
270
271#if HAVE_DEV_URANDOM
272 /* increase session identifier entropy */
273 if (SESSION_G(entropy_length) == 0 || SESSION_G(entropy_file) == NULL) {
274 SESSION_G(entropy_length) = 16;
275 SESSION_G(entropy_file) = pestrdup("/dev/urandom", 1);
276 }
277#endif
278}
279
280// void suhosin_unhook_session()
281// {
282// if (old_OnUpdateSaveHandler == NULL) {
283// return;
284// }
285//
286// /* retrieve pointer to session.save_handler ini entry */
287// zend_ini_entry *ini_entry;
288// if ((ini_entry = zend_hash_find(EG(ini_directives), ZEND_STRL("session.save_handler"))) == NULL) {
289// return;
290// }
291// ini_entry->on_modify = old_OnUpdateSaveHandler;
292// old_OnUpdateSaveHandler = NULL;
293// }
294
295#else /* HAVE_PHP_SESSION */
296
297#warning BUILDING SUHOSIN WITHOUT SESSION SUPPORT
298
299#endif /* HAVE_PHP_SESSION */
300
301
302/*
303 * Local variables:
304 * tab-width: 4
305 * c-basic-offset: 4
306 * End:
307 * vim600: sw=4 ts=4 fdm=marker
308 * vim<600: sw=4 ts=4
309 */
diff --git a/suhosin7.c b/suhosin7.c
index 7986f2a..6d6655a 100644
--- a/suhosin7.c
+++ b/suhosin7.c
@@ -377,13 +377,13 @@ PHP_INI_BEGIN()
377 // STD_S7_INI_ENTRY("suhosin.sql.union", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateSQLLong, sql_union) 377 // STD_S7_INI_ENTRY("suhosin.sql.union", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateSQLLong, sql_union)
378 378
379#ifdef HAVE_PHP_SESSION 379#ifdef HAVE_PHP_SESSION
380 // STD_S7_INI_BOOLEAN("suhosin.session.encrypt", "1", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateMiscBool, session_encrypt) 380 STD_S7_INI_BOOLEAN("suhosin.session.encrypt", "1", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateMiscBool, session_encrypt)
381 STD_S7_INI_ENTRY("suhosin.session.cryptkey", "", PHP_INI_ALL, OnUpdateMiscString, session_cryptkey) 381 STD_S7_INI_ENTRY("suhosin.session.cryptkey", "", PHP_INI_ALL, OnUpdateMiscString, session_cryptkey)
382 // STD_S7_INI_BOOLEAN("suhosin.session.cryptua", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateMiscBool, session_cryptua) 382 STD_S7_INI_BOOLEAN("suhosin.session.cryptua", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateMiscBool, session_cryptua)
383 // STD_S7_INI_BOOLEAN("suhosin.session.cryptdocroot", "1", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateMiscBool, session_cryptdocroot) 383 STD_S7_INI_BOOLEAN("suhosin.session.cryptdocroot", "1", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateMiscBool, session_cryptdocroot)
384 // STD_S7_INI_ENTRY("suhosin.session.cryptraddr", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMiscLong, session_cryptraddr) 384 STD_S7_INI_ENTRY("suhosin.session.cryptraddr", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMiscLong, session_cryptraddr)
385 // STD_S7_INI_ENTRY("suhosin.session.checkraddr", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMiscLong, session_checkraddr) 385 STD_S7_INI_ENTRY("suhosin.session.checkraddr", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMiscLong, session_checkraddr)
386 // STD_S7_INI_ENTRY("suhosin.session.max_id_length", "128", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMiscLong, session_max_id_length) 386 STD_S7_INI_ENTRY("suhosin.session.max_id_length", "128", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMiscLong, session_max_id_length)
387#else /* HAVE_PHP_SESSION */ 387#else /* HAVE_PHP_SESSION */
388#warning BUILDING SUHOSIN WITHOUT SESSION SUPPORT. THIS IS A BAD IDEA! 388#warning BUILDING SUHOSIN WITHOUT SESSION SUPPORT. THIS IS A BAD IDEA!
389#ifndef SUHOSIN_WITHOUT_SESSION 389#ifndef SUHOSIN_WITHOUT_SESSION
@@ -518,9 +518,11 @@ PHP_MINIT_FUNCTION(suhosin7)
518 suhosin_hook_register_server_variables(); 518 suhosin_hook_register_server_variables();
519 suhosin_hook_header_handler(); 519 suhosin_hook_header_handler();
520 suhosin_hook_execute(); 520 suhosin_hook_execute();
521
522 suhosin_hook_memory_limit(); 521 suhosin_hook_memory_limit();
523 // suhosin_hook_sha256(); 522 // suhosin_hook_sha256();
523#ifdef HAVE_PHP_SESSION
524 suhosin_hook_session();
525#endif
524 526
525 return SUCCESS; 527 return SUCCESS;
526} 528}
diff --git a/tests/session/PHPSESSID_max_id_length_ok.phpt b/tests/session/PHPSESSID_max_id_length_ok.phpt
new file mode 100644
index 0000000..2673d08
--- /dev/null
+++ b/tests/session/PHPSESSID_max_id_length_ok.phpt
@@ -0,0 +1,16 @@
1--TEST--
2PHPSESSID session id not too long
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--INI--
6suhosin.session.max_id_length=32
7session.hash_bits_per_character=4
8--COOKIE--
9PHPSESSID=12345678901234567890123456789012;
10--FILE--
11<?php
12session_start();
13echo session_id();
14?>
15--EXPECTF--
1612345678901234567890123456789012 \ No newline at end of file
diff --git a/tests/session/PHPSESSID_max_id_length_toolong.phpt b/tests/session/PHPSESSID_max_id_length_toolong.phpt
new file mode 100644
index 0000000..6bd71fb
--- /dev/null
+++ b/tests/session/PHPSESSID_max_id_length_toolong.phpt
@@ -0,0 +1,16 @@
1--TEST--
2PHPSESSID session id too long
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--INI--
6suhosin.session.max_id_length=32
7session.hash_bits_per_character=4
8--COOKIE--
9PHPSESSID=123456789012345678901234567890123;
10--FILE--
11<?php
12session_start();
13echo strlen(session_id());
14?>
15--EXPECTF--
1632 \ No newline at end of file
diff --git a/tests/session/crypt.checkraddr_4.phpt b/tests/session/crypt.checkraddr_4.phpt
new file mode 100644
index 0000000..42ac96a
--- /dev/null
+++ b/tests/session/crypt.checkraddr_4.phpt
@@ -0,0 +1,29 @@
1--TEST--
2session encryption with checkraddr=4
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--ENV--
6return <<<END
7REMOTE_ADDR=127.0.0.1
8PHPSESSID=test
9END;
10--INI--
11suhosin.session.encrypt=On
12suhosin.session.cryptkey=D3F4UL7
13suhosin.session.cryptua=Off
14suhosin.session.cryptdocroot=Off
15suhosin.session.cryptraddr=0
16suhosin.session.checkraddr=4
17--FILE--
18<?php
19include "sessionhandler.inc";
20
21session_test_start(new RemoteAddrSessionHandler());
22var_dump($_SESSION);
23
24?>
25--EXPECTF--
26array(1) {
27 ["a"]=>
28 string(1) "b"
29}
diff --git a/tests/session/crypt.checkraddr_4_incorrect.phpt b/tests/session/crypt.checkraddr_4_incorrect.phpt
new file mode 100644
index 0000000..cc468b8
--- /dev/null
+++ b/tests/session/crypt.checkraddr_4_incorrect.phpt
@@ -0,0 +1,27 @@
1--TEST--
2session encryption with checkraddr=4 and incorrect REMOTE_ADDR
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--ENV--
6return <<<END
7REMOTE_ADDR=127.0.0.2
8PHPSESSID=test
9END;
10--INI--
11suhosin.session.encrypt=On
12suhosin.session.cryptkey=D3F4UL7
13suhosin.session.cryptua=Off
14suhosin.session.cryptdocroot=Off
15suhosin.session.cryptraddr=0
16suhosin.session.checkraddr=4
17--FILE--
18<?php
19include "sessionhandler.inc";
20
21session_test_start(new RemoteAddrSessionHandler());
22var_dump($_SESSION);
23
24?>
25--EXPECTF--
26array(0) {
27}
diff --git a/tests/session/crypt.docroot.phpt b/tests/session/crypt.docroot.phpt
new file mode 100644
index 0000000..d5b6fc6
--- /dev/null
+++ b/tests/session/crypt.docroot.phpt
@@ -0,0 +1,25 @@
1--TEST--
2session with encryption using docroot
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--ENV--
6return <<<END
7DOCUMENT_ROOT=/var/www
8END;
9--INI--
10suhosin.session.encrypt=On
11suhosin.session.cryptkey=D3F4UL7
12suhosin.session.cryptua=Off
13suhosin.session.cryptdocroot=On
14suhosin.session.cryptraddr=0
15suhosin.session.checkraddr=0
16--FILE--
17<?php
18include "sessionhandler.inc";
19session_test_start();
20$_SESSION['a'] = 'b';
21
22
23?>
24--EXPECTF--
25SESSION: NKChb1rdctXd-Acz0uzOYVnJT_J2mxYRVUgSh0w5mlk.
diff --git a/tests/session/crypt.key_default.phpt b/tests/session/crypt.key_default.phpt
new file mode 100644
index 0000000..8e4f12a
--- /dev/null
+++ b/tests/session/crypt.key_default.phpt
@@ -0,0 +1,21 @@
1--TEST--
2session with encryption default key
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--INI--
6suhosin.session.encrypt=On
7suhosin.session.cryptkey=D3F4UL7
8suhosin.session.cryptua=Off
9suhosin.session.cryptdocroot=Off
10suhosin.session.cryptraddr=0
11suhosin.session.checkraddr=0
12--FILE--
13<?php
14include "sessionhandler.inc";
15session_test_start();
16$_SESSION['a'] = 'b';
17
18
19?>
20--EXPECTF--
21SESSION: RIuy2LSSd3_s3hhDCnN89bNWyCnhvNAO0YUq7OQKuJc.
diff --git a/tests/session/crypt.key_empty.phpt b/tests/session/crypt.key_empty.phpt
new file mode 100644
index 0000000..3e5da11
--- /dev/null
+++ b/tests/session/crypt.key_empty.phpt
@@ -0,0 +1,21 @@
1--TEST--
2session with encryption key empty
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--INI--
6suhosin.session.encrypt=On
7suhosin.session.cryptkey=
8suhosin.session.cryptua=Off
9suhosin.session.cryptdocroot=Off
10suhosin.session.cryptraddr=0
11suhosin.session.checkraddr=0
12--FILE--
13<?php
14include "sessionhandler.inc";
15session_test_start();
16$_SESSION['a'] = 'b';
17
18
19?>
20--EXPECTF--
21SESSION: RIuy2LSSd3_s3hhDCnN89bNWyCnhvNAO0YUq7OQKuJc.
diff --git a/tests/session/crypt.key_empty_remote_addr.phpt b/tests/session/crypt.key_empty_remote_addr.phpt
new file mode 100644
index 0000000..cf1292a
--- /dev/null
+++ b/tests/session/crypt.key_empty_remote_addr.phpt
@@ -0,0 +1,25 @@
1--TEST--
2session with encryption key empty and REMOTE_ADDR set
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--ENV--
6return <<<END
7REMOTE_ADDR=127.0.0.1
8END;
9--INI--
10suhosin.session.encrypt=On
11suhosin.session.cryptkey=
12suhosin.session.cryptua=Off
13suhosin.session.cryptdocroot=Off
14suhosin.session.cryptraddr=0
15suhosin.session.checkraddr=0
16--FILE--
17<?php
18include "sessionhandler.inc";
19session_test_start();
20$_SESSION['a'] = 'b';
21
22
23?>
24--EXPECTF--
25SESSION: j1YTvIOAUqxZMjuJ_ZnHPHWY5XEayycsr7O94aMzmBQ.
diff --git a/tests/session/crypt.no_encryption.phpt b/tests/session/crypt.no_encryption.phpt
new file mode 100644
index 0000000..6b6bc97
--- /dev/null
+++ b/tests/session/crypt.no_encryption.phpt
@@ -0,0 +1,15 @@
1--TEST--
2session without encryption
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--INI--
6suhosin.session.encrypt=Off
7--FILE--
8<?php
9include "sessionhandler.inc";
10session_test_start();
11$_SESSION['a'] = 'b';
12
13?>
14--EXPECTF--
15SESSION: a|s:1:"b"; \ No newline at end of file
diff --git a/tests/session/crypt.raddr_1.phpt b/tests/session/crypt.raddr_1.phpt
new file mode 100644
index 0000000..2070d03
--- /dev/null
+++ b/tests/session/crypt.raddr_1.phpt
@@ -0,0 +1,25 @@
1--TEST--
2session with encryption using REMOTE_ADDR (cryptraddr=1)
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--ENV--
6return <<<END
7REMOTE_ADDR=127.0.0.1
8END;
9--INI--
10suhosin.session.encrypt=On
11suhosin.session.cryptkey=D3F4UL7
12suhosin.session.cryptua=Off
13suhosin.session.cryptdocroot=Off
14suhosin.session.cryptraddr=1
15suhosin.session.checkraddr=0
16--FILE--
17<?php
18include "sessionhandler.inc";
19session_test_start();
20$_SESSION['a'] = 'b';
21
22
23?>
24--EXPECTF--
25SESSION: wkiQGgZgWnBFDyCs_4QYD_oaw_m35l_5I35XRg0wX_g.
diff --git a/tests/session/crypt.raddr_2.phpt b/tests/session/crypt.raddr_2.phpt
new file mode 100644
index 0000000..b8c21bc
--- /dev/null
+++ b/tests/session/crypt.raddr_2.phpt
@@ -0,0 +1,25 @@
1--TEST--
2session with encryption using REMOTE_ADDR (cryptraddr=2)
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--ENV--
6return <<<END
7REMOTE_ADDR=127.0.0.1
8END;
9--INI--
10suhosin.session.encrypt=On
11suhosin.session.cryptkey=D3F4UL7
12suhosin.session.cryptua=Off
13suhosin.session.cryptdocroot=Off
14suhosin.session.cryptraddr=2
15suhosin.session.checkraddr=0
16--FILE--
17<?php
18include "sessionhandler.inc";
19session_test_start();
20$_SESSION['a'] = 'b';
21
22
23?>
24--EXPECTF--
25SESSION: WDyvE0R4mUqvOG6e5VzhfgWMjfCWSFC5bNNI_3dIT3w.
diff --git a/tests/session/crypt.raddr_3.phpt b/tests/session/crypt.raddr_3.phpt
new file mode 100644
index 0000000..afe2729
--- /dev/null
+++ b/tests/session/crypt.raddr_3.phpt
@@ -0,0 +1,25 @@
1--TEST--
2session with encryption using REMOTE_ADDR (cryptraddr=3)
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--ENV--
6return <<<END
7REMOTE_ADDR=127.0.0.1
8END;
9--INI--
10suhosin.session.encrypt=On
11suhosin.session.cryptkey=D3F4UL7
12suhosin.session.cryptua=Off
13suhosin.session.cryptdocroot=Off
14suhosin.session.cryptraddr=3
15suhosin.session.checkraddr=0
16--FILE--
17<?php
18include "sessionhandler.inc";
19session_test_start();
20$_SESSION['a'] = 'b';
21
22
23?>
24--EXPECTF--
25SESSION: 6kLKLrgCmlOuEPXPON_K5SWHLuIbHdLsh4MJ0QtTFj8.
diff --git a/tests/session/crypt.raddr_4.phpt b/tests/session/crypt.raddr_4.phpt
new file mode 100644
index 0000000..28b4098
--- /dev/null
+++ b/tests/session/crypt.raddr_4.phpt
@@ -0,0 +1,25 @@
1--TEST--
2session with encryption using REMOTE_ADDR (cryptraddr=4)
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--ENV--
6return <<<END
7REMOTE_ADDR=127.0.0.1
8END;
9--INI--
10suhosin.session.encrypt=On
11suhosin.session.cryptkey=D3F4UL7
12suhosin.session.cryptua=Off
13suhosin.session.cryptdocroot=Off
14suhosin.session.cryptraddr=4
15suhosin.session.checkraddr=0
16--FILE--
17<?php
18include "sessionhandler.inc";
19session_test_start();
20$_SESSION['a'] = 'b';
21
22
23?>
24--EXPECTF--
25SESSION: QYSbWh8enETvdtKfao8G6aiXqK7_lhzFmRNYa2lo-UM.
diff --git a/tests/session/crypt.ua.phpt b/tests/session/crypt.ua.phpt
new file mode 100644
index 0000000..4c53273
--- /dev/null
+++ b/tests/session/crypt.ua.phpt
@@ -0,0 +1,25 @@
1--TEST--
2session with encryption using ua
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--ENV--
6return <<<END
7HTTP_USER_AGENT=test
8END;
9--INI--
10suhosin.session.encrypt=On
11suhosin.session.cryptkey=D3F4UL7
12suhosin.session.cryptua=On
13suhosin.session.cryptdocroot=Off
14suhosin.session.cryptraddr=0
15suhosin.session.checkraddr=0
16--FILE--
17<?php
18include "sessionhandler.inc";
19session_test_start();
20$_SESSION['a'] = 'b';
21
22
23?>
24--EXPECTF--
25SESSION: 3pVZdIv7vHG-PwO_rLQLUGerd4L_UX60xJoAM-IoVC4.
diff --git a/tests/session/max_id_length_ok.phpt b/tests/session/max_id_length_ok.phpt
new file mode 100644
index 0000000..dbecebd
--- /dev/null
+++ b/tests/session/max_id_length_ok.phpt
@@ -0,0 +1,16 @@
1--TEST--
2session id not too long
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--INI--
6suhosin.session.max_id_length=32
7session.hash_bits_per_character=4
8session.use_strict_mode=0
9--FILE--
10<?php
11session_id('12345678901234567890123456789012');
12session_start();
13echo session_id();
14?>
15--EXPECTF--
1612345678901234567890123456789012
diff --git a/tests/session/max_id_length_toolong.phpt b/tests/session/max_id_length_toolong.phpt
new file mode 100644
index 0000000..a8ec4cc
--- /dev/null
+++ b/tests/session/max_id_length_toolong.phpt
@@ -0,0 +1,15 @@
1--TEST--
2session id too long
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--INI--
6suhosin.session.max_id_length=32
7session.hash_bits_per_character=4
8--FILE--
9<?php
10session_id('123456789012345678901234567890123');
11session_start();
12echo strlen(session_id());
13?>
14--EXPECTF--
1532 \ No newline at end of file
diff --git a/tests/session/session_recursive_crash.phpt b/tests/session/session_recursive_crash.phpt
new file mode 100644
index 0000000..62cb9cd
--- /dev/null
+++ b/tests/session/session_recursive_crash.phpt
@@ -0,0 +1,25 @@
1--TEST--
2session SessionHandler() recursive crash
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--ENV--
6return <<<END
7HTTP_USER_AGENT=test
8END;
9--INI--
10suhosin.session.encrypt=On
11suhosin.session.cryptkey=D3F4UL7
12suhosin.session.cryptua=On
13suhosin.session.cryptdocroot=Off
14suhosin.session.cryptraddr=0
15suhosin.session.checkraddr=0
16--FILE--
17<?php
18session_set_save_handler(new SessionHandler(), true);
19$_SESSION['a'] = 'b';
20var_dump($_SESSION);
21--EXPECTF--
22array(1) {
23 ["a"]=>
24 string(1) "b"
25}
diff --git a/tests/session/session_recursive_crash2.phpt b/tests/session/session_recursive_crash2.phpt
new file mode 100644
index 0000000..2a32226
--- /dev/null
+++ b/tests/session/session_recursive_crash2.phpt
@@ -0,0 +1,61 @@
1--TEST--
2session user handler recursive crash - issue suhosin#60
3--SKIPIF--
4<?php include "../skipifcli.inc"; ?>
5--ENV--
6return <<<END
7HTTP_USER_AGENT=test
8END;
9--INI--
10suhosin.session.encrypt=On
11suhosin.session.cryptkey=D3F4UL7
12suhosin.session.cryptua=On
13suhosin.session.cryptdocroot=Off
14suhosin.session.cryptraddr=0
15suhosin.session.checkraddr=0
16--FILE--
17<?php
18$foo = "";
19
20class MySessionHandlerA implements SessionHandlerInterface
21{
22 public function close() {return TRUE;}
23 public function destroy($session_id) {return TRUE;}
24 public function gc($maxlifetime) {return TRUE;}
25 public function open($save_path, $name) { global $foo; $foo .= "A\n"; return TRUE;}
26 public function read($session_id ) {return TRUE;}
27 public function write($session_id, $session_data) {return TRUE;}
28}
29
30session_set_save_handler(new MySessionHandlerA(), true);
31session_start();
32session_destroy();
33
34//
35
36class MySessionHandlerB extends MySessionHandlerA
37{
38 public function open($save_path, $name) { global $foo; $foo .= "B\n"; return TRUE;}
39}
40
41session_set_save_handler(new MySessionHandlerB(), true);
42session_start();
43session_destroy();
44
45//
46
47class MySessionHandlerC extends MySessionHandlerA
48{
49 public function open($save_path, $name) { global $foo; $foo .= "C\n"; return TRUE;}
50}
51
52session_set_save_handler(new MySessionHandlerC(), true);
53session_start();
54session_destroy();
55
56
57echo $foo;
58--EXPECTF--
59A
60B
61C
diff --git a/tests/session/sessionhandler.inc b/tests/session/sessionhandler.inc
new file mode 100644
index 0000000..b8bc7bd
--- /dev/null
+++ b/tests/session/sessionhandler.inc
@@ -0,0 +1,43 @@
1<?php
2
3
4class GenericSessionHandler implements SessionHandlerInterface
5{
6 function open($savePath, $sessionName) { return true; }
7
8 function close() { return true; }
9
10 function read($id) { return (string)""; }
11
12 function write($id, $data) { return true; }
13
14 function destroy($id) { return true; }
15
16 function gc($maxlifetime) { return true; }
17
18}
19class WriteSessionHandler extends GenericSessionHandler
20{
21 function write($id, $data)
22 {
23 echo "SESSION: $data\n";
24 return true;
25 }
26}
27class RemoteAddrSessionHandler extends GenericSessionHandler
28{
29 ## key empty and REMOTE_ADDR set to 127.0.0.1
30 function read($id) { return (string)"j1YTvIOAUqxZMjuJ_ZnHPHWY5XEayycsr7O94aMzmBQ."; }
31}
32
33
34function session_test_start($handler=null) {
35 if (!$handler) {
36 $handler = new WriteSessionHandler();
37 }
38 session_set_save_handler($handler, true);
39 session_start();
40 return $handler;
41}
42
43?>