diff options
| author | Ben Fuhrmannek | 2021-09-16 12:43:11 +0200 |
|---|---|---|
| committer | Ben Fuhrmannek | 2021-09-16 12:43:11 +0200 |
| commit | a99c0b3ba7ebbd27fd62f2bde3963354c2bf55e3 (patch) | |
| tree | 4890517eb3578b3ba015ae9e5c5f88e46f2a33ca /src | |
| parent | 6e07cdb870513270a3c08abc7ecdca64ad2af400 (diff) | |
ported sid min/max restriction from suhosin
Diffstat (limited to 'src')
| -rw-r--r-- | src/snuffleupagus.c | 2 | ||||
| -rw-r--r-- | src/sp_config.h | 4 | ||||
| -rw-r--r-- | src/sp_config_keywords.c | 2 | ||||
| -rw-r--r-- | src/sp_session.c | 27 | ||||
| -rw-r--r-- | src/tests/sid_too_long.phpt | 16 | ||||
| -rw-r--r-- | src/tests/sid_too_short.phpt | 16 |
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 { | |||
| 81 | typedef struct { | 81 | typedef 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 | ||
| 86 | typedef struct { | 88 | typedef 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); | |||
| 24 | static int (*previous_sessionRINIT)(INIT_FUNC_ARGS) = NULL; | 24 | static int (*previous_sessionRINIT)(INIT_FUNC_ARGS) = NULL; |
| 25 | static ZEND_INI_MH((*old_OnUpdateSaveHandler)) = NULL; | 25 | static ZEND_INI_MH((*old_OnUpdateSaveHandler)) = NULL; |
| 26 | 26 | ||
| 27 | static 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 | |||
| 27 | static int sp_hook_s_read(PS_READ_ARGS) { | 40 | static 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 | ||
| 53 | static int sp_hook_s_write(PS_WRITE_ARGS) { | 67 | static 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-- | ||
| 2 | SESSION ID too long | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php if (!extension_loaded("snuffleupagus")) print "skip"; ?> | ||
| 5 | --INI-- | ||
| 6 | sp.configuration_file={PWD}/config/sid_length_limit.ini | ||
| 7 | --FILE-- | ||
| 8 | <?php | ||
| 9 | session_id('123456789012345678901234567890123'); | ||
| 10 | session_start(); | ||
| 11 | echo strlen(session_id()); | ||
| 12 | ?> | ||
| 13 | --EXPECTF-- | ||
| 14 | Fatal error: [snuffleupagus][0.0.0.0][session][drop] Session ID is too long in %a.php on line %d | ||
| 15 | |||
| 16 | Fatal 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-- | ||
| 2 | SESSION ID too short | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php if (!extension_loaded("snuffleupagus")) print "skip"; ?> | ||
| 5 | --INI-- | ||
| 6 | sp.configuration_file={PWD}/config/sid_length_limit.ini | ||
| 7 | --FILE-- | ||
| 8 | <?php | ||
| 9 | session_id('123'); | ||
| 10 | session_start(); | ||
| 11 | echo strlen(session_id()); | ||
| 12 | ?> | ||
| 13 | --EXPECTF-- | ||
| 14 | Fatal error: [snuffleupagus][0.0.0.0][session][drop] Session ID is too short in %a.php on line %d | ||
| 15 | |||
| 16 | Fatal error: [snuffleupagus][0.0.0.0][session][drop] Session ID is too short in Unknown on line 0 \ No newline at end of file | ||
