summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/snuffleupagus.c2
-rw-r--r--src/sp_config.h4
-rw-r--r--src/sp_config_keywords.c2
-rw-r--r--src/sp_session.c27
-rw-r--r--src/tests/sid_too_long.phpt16
-rw-r--r--src/tests/sid_too_short.phpt16
6 files changed, 61 insertions, 6 deletions
diff --git a/src/snuffleupagus.c b/src/snuffleupagus.c
index 50711f0..84ab171 100644
--- a/src/snuffleupagus.c
+++ b/src/snuffleupagus.c
@@ -365,7 +365,7 @@ static PHP_INI_MH(OnUpdateConfiguration) {
365 hook_stream_wrappers(); 365 hook_stream_wrappers();
366 } 366 }
367 367
368 if (SNUFFLEUPAGUS_G(config).config_session->encrypt) { 368 if (SNUFFLEUPAGUS_G(config).config_session->encrypt || SNUFFLEUPAGUS_G(config).config_session->sid_min_length || SNUFFLEUPAGUS_G(config).config_session->sid_max_length) {
369 hook_session(); 369 hook_session();
370 } 370 }
371 371
diff --git a/src/sp_config.h b/src/sp_config.h
index af9b905..df36976 100644
--- a/src/sp_config.h
+++ b/src/sp_config.h
@@ -81,6 +81,8 @@ typedef struct {
81typedef struct { 81typedef struct {
82 bool encrypt; 82 bool encrypt;
83 bool simulation; 83 bool simulation;
84 u_long sid_min_length;
85 u_long sid_max_length;
84} sp_config_session; 86} sp_config_session;
85 87
86typedef struct { 88typedef struct {
@@ -292,6 +294,8 @@ typedef struct {
292#define SP_TOKEN_MAX_EXECUTION_DEPTH "max_execution_depth" 294#define SP_TOKEN_MAX_EXECUTION_DEPTH "max_execution_depth"
293#define SP_TOKEN_SERVER_ENCODE "server_encode" 295#define SP_TOKEN_SERVER_ENCODE "server_encode"
294#define SP_TOKEN_SERVER_STRIP "server_strip" 296#define SP_TOKEN_SERVER_STRIP "server_strip"
297#define SP_TOKEN_SID_MIN_LENGTH "sid_min_length"
298#define SP_TOKEN_SID_MAX_LENGTH "sid_max_length"
295 299
296// upload_validator 300// upload_validator
297#define SP_TOKEN_UPLOAD_SCRIPT "script" 301#define SP_TOKEN_UPLOAD_SCRIPT "script"
diff --git a/src/sp_config_keywords.c b/src/sp_config_keywords.c
index 38b8526..bd8a9a1 100644
--- a/src/sp_config_keywords.c
+++ b/src/sp_config_keywords.c
@@ -33,6 +33,8 @@ SP_PARSE_FN(parse_session) {
33 {parse_empty, SP_TOKEN_ENCRYPT, &(cfg->encrypt)}, 33 {parse_empty, SP_TOKEN_ENCRYPT, &(cfg->encrypt)},
34 {parse_empty, SP_TOKEN_SIMULATION, &(cfg->simulation)}, 34 {parse_empty, SP_TOKEN_SIMULATION, &(cfg->simulation)},
35 {parse_empty, SP_TOKEN_SIM, &(cfg->simulation)}, 35 {parse_empty, SP_TOKEN_SIM, &(cfg->simulation)},
36 {parse_ulong, SP_TOKEN_SID_MIN_LENGTH, &(cfg->sid_min_length)},
37 {parse_ulong, SP_TOKEN_SID_MAX_LENGTH, &(cfg->sid_max_length)},
36 {0, 0, 0}}; 38 {0, 0, 0}};
37 39
38 SP_PROCESS_CONFIG_KEYWORDS_ERR(); 40 SP_PROCESS_CONFIG_KEYWORDS_ERR();
diff --git a/src/sp_session.c b/src/sp_session.c
index 7fa4937..64233d1 100644
--- a/src/sp_session.c
+++ b/src/sp_session.c
@@ -24,21 +24,35 @@ static int (*old_s_write)(PS_WRITE_ARGS);
24static int (*previous_sessionRINIT)(INIT_FUNC_ARGS) = NULL; 24static int (*previous_sessionRINIT)(INIT_FUNC_ARGS) = NULL;
25static ZEND_INI_MH((*old_OnUpdateSaveHandler)) = NULL; 25static ZEND_INI_MH((*old_OnUpdateSaveHandler)) = NULL;
26 26
27static void check_sid_length(zend_string *sid) {
28 const sp_config_session *cfg = SNUFFLEUPAGUS_G(config).config_session;
29
30 if (sid) {
31 if (cfg->sid_min_length && ZSTR_LEN(sid) < cfg->sid_min_length) {
32 sp_log_auto("session", cfg->simulation, "Session ID is too short");
33 }
34 if (cfg->sid_max_length && ZSTR_LEN(sid) > cfg->sid_max_length) {
35 sp_log_auto("session", cfg->simulation, "Session ID is too long");
36 }
37 }
38}
39
27static int sp_hook_s_read(PS_READ_ARGS) { 40static int sp_hook_s_read(PS_READ_ARGS) {
41 const sp_config_session *cfg = SNUFFLEUPAGUS_G(config).config_session;
42 check_sid_length(key);
43
28 int r = old_s_read(mod_data, key, val, maxlifetime); 44 int r = old_s_read(mod_data, key, val, maxlifetime);
29 const sp_config_session *config_session =
30 SNUFFLEUPAGUS_G(config).config_session;
31 45
32 if ((NULL == val) || (NULL == *val) || (0 == ZSTR_LEN(*val))) { 46 if ((NULL == val) || (NULL == *val) || (0 == ZSTR_LEN(*val))) {
33 return r; 47 return r;
34 } 48 }
35 49
36 if (r == SUCCESS && config_session->encrypt) { 50 if (r == SUCCESS && cfg->encrypt) {
37 zend_string *orig_val = *val; 51 zend_string *orig_val = *val;
38 zval val_zval; 52 zval val_zval;
39 ZVAL_PSTRINGL(&val_zval, ZSTR_VAL(*val), ZSTR_LEN(*val)); 53 ZVAL_PSTRINGL(&val_zval, ZSTR_VAL(*val), ZSTR_LEN(*val));
40 54
41 int ret = decrypt_zval(&val_zval, config_session->simulation, NULL); 55 int ret = decrypt_zval(&val_zval, cfg->simulation, NULL);
42 if (ZEND_HASH_APPLY_KEEP != ret) { 56 if (ZEND_HASH_APPLY_KEEP != ret) {
43 zend_bailout(); 57 zend_bailout();
44 } 58 }
@@ -51,7 +65,10 @@ static int sp_hook_s_read(PS_READ_ARGS) {
51} 65}
52 66
53static int sp_hook_s_write(PS_WRITE_ARGS) { 67static int sp_hook_s_write(PS_WRITE_ARGS) {
54 if (ZSTR_LEN(val) > 0 && SNUFFLEUPAGUS_G(config).config_session->encrypt) { 68 const sp_config_session *cfg = SNUFFLEUPAGUS_G(config).config_session;
69 check_sid_length(key);
70
71 if (ZSTR_LEN(val) > 0 && cfg->encrypt) {
55 zend_string *new_val = encrypt_zval(val); 72 zend_string *new_val = encrypt_zval(val);
56 return old_s_write(mod_data, key, new_val, maxlifetime); 73 return old_s_write(mod_data, key, new_val, maxlifetime);
57 } 74 }
diff --git a/src/tests/sid_too_long.phpt b/src/tests/sid_too_long.phpt
new file mode 100644
index 0000000..235b166
--- /dev/null
+++ b/src/tests/sid_too_long.phpt
@@ -0,0 +1,16 @@
1--TEST--
2SESSION ID too long
3--SKIPIF--
4<?php if (!extension_loaded("snuffleupagus")) print "skip"; ?>
5--INI--
6sp.configuration_file={PWD}/config/sid_length_limit.ini
7--FILE--
8<?php
9session_id('123456789012345678901234567890123');
10session_start();
11echo strlen(session_id());
12?>
13--EXPECTF--
14Fatal error: [snuffleupagus][0.0.0.0][session][drop] Session ID is too long in %a.php on line %d
15
16Fatal error: [snuffleupagus][0.0.0.0][session][drop] Session ID is too long in Unknown on line 0 \ No newline at end of file
diff --git a/src/tests/sid_too_short.phpt b/src/tests/sid_too_short.phpt
new file mode 100644
index 0000000..0d9d514
--- /dev/null
+++ b/src/tests/sid_too_short.phpt
@@ -0,0 +1,16 @@
1--TEST--
2SESSION ID too short
3--SKIPIF--
4<?php if (!extension_loaded("snuffleupagus")) print "skip"; ?>
5--INI--
6sp.configuration_file={PWD}/config/sid_length_limit.ini
7--FILE--
8<?php
9session_id('123');
10session_start();
11echo strlen(session_id());
12?>
13--EXPECTF--
14Fatal error: [snuffleupagus][0.0.0.0][session][drop] Session ID is too short in %a.php on line %d
15
16Fatal error: [snuffleupagus][0.0.0.0][session][drop] Session ID is too short in Unknown on line 0 \ No newline at end of file