diff options
| author | jvoisin | 2018-01-04 15:59:59 +0100 |
|---|---|---|
| committer | GitHub | 2018-01-04 15:59:59 +0100 |
| commit | 3b113be573cdbca20ce9ec9c0a6efb25ccf51db5 (patch) | |
| tree | 5fabbd1da7cd740f26354ffbd2234eba71ffdead /src | |
| parent | 84e423300c440e96c34ada2620e0f78f827592e8 (diff) | |
Eval blacklist
Add support for eval filtering, only blacklist for now
Diffstat (limited to 'src')
| -rw-r--r-- | src/php_snuffleupagus.h | 3 | ||||
| -rw-r--r-- | src/snuffleupagus.c | 9 | ||||
| -rw-r--r-- | src/sp_config.c | 1 | ||||
| -rw-r--r-- | src/sp_config.h | 12 | ||||
| -rw-r--r-- | src/sp_config_keywords.c | 19 | ||||
| -rw-r--r-- | src/sp_config_keywords.h | 1 | ||||
| -rw-r--r-- | src/sp_disabled_functions.c | 40 | ||||
| -rw-r--r-- | src/sp_execute.c | 3 | ||||
| -rw-r--r-- | src/sp_harden_rand.c | 9 | ||||
| -rw-r--r-- | src/sp_unserialize.c | 2 | ||||
| -rw-r--r-- | src/tests/config/eval_backlist.ini | 1 | ||||
| -rw-r--r-- | src/tests/config/eval_backlist_list.ini | 1 | ||||
| -rw-r--r-- | src/tests/config/eval_backlist_simulation.ini | 1 | ||||
| -rw-r--r-- | src/tests/eval_backlist.phpt | 16 | ||||
| -rw-r--r-- | src/tests/eval_backlist_list.phpt | 16 | ||||
| -rw-r--r-- | src/tests/eval_backlist_simulation.phpt | 17 | ||||
| -rw-r--r-- | src/tests/nested_eval_blacklist.phpt | 28 |
17 files changed, 171 insertions, 8 deletions
diff --git a/src/php_snuffleupagus.h b/src/php_snuffleupagus.h index d7c3e27..fb90d1c 100644 --- a/src/php_snuffleupagus.h +++ b/src/php_snuffleupagus.h | |||
| @@ -58,10 +58,12 @@ extern zend_module_entry snuffleupagus_module_entry; | |||
| 58 | #endif | 58 | #endif |
| 59 | 59 | ||
| 60 | ZEND_BEGIN_MODULE_GLOBALS(snuffleupagus) | 60 | ZEND_BEGIN_MODULE_GLOBALS(snuffleupagus) |
| 61 | bool in_eval; | ||
| 61 | sp_config config; | 62 | sp_config config; |
| 62 | bool is_config_valid; | 63 | bool is_config_valid; |
| 63 | HashTable *disabled_functions_hook; | 64 | HashTable *disabled_functions_hook; |
| 64 | HashTable *sp_internal_functions_hook; | 65 | HashTable *sp_internal_functions_hook; |
| 66 | HashTable *sp_eval_filter_functions_hook; | ||
| 65 | ZEND_END_MODULE_GLOBALS(snuffleupagus) | 67 | ZEND_END_MODULE_GLOBALS(snuffleupagus) |
| 66 | 68 | ||
| 67 | #define SNUFFLEUPAGUS_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(snuffleupagus, v) | 69 | #define SNUFFLEUPAGUS_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(snuffleupagus, v) |
| @@ -83,6 +85,7 @@ ZEND_TSRMLS_CACHE_EXTERN() | |||
| 83 | #endif | 85 | #endif |
| 84 | 86 | ||
| 85 | PHP_FUNCTION(check_disabled_function); | 87 | PHP_FUNCTION(check_disabled_function); |
| 88 | PHP_FUNCTION(eval_filter_callback); | ||
| 86 | 89 | ||
| 87 | static inline void sp_terminate() { zend_bailout(); } | 90 | static inline void sp_terminate() { zend_bailout(); } |
| 88 | 91 | ||
diff --git a/src/snuffleupagus.c b/src/snuffleupagus.c index dd2d941..a3a2fa8 100644 --- a/src/snuffleupagus.c +++ b/src/snuffleupagus.c | |||
| @@ -53,6 +53,8 @@ ZEND_DLEXPORT zend_extension zend_extension_entry = { | |||
| 53 | STANDARD_ZEND_EXTENSION_PROPERTIES}; | 53 | STANDARD_ZEND_EXTENSION_PROPERTIES}; |
| 54 | 54 | ||
| 55 | PHP_GINIT_FUNCTION(snuffleupagus) { | 55 | PHP_GINIT_FUNCTION(snuffleupagus) { |
| 56 | snuffleupagus_globals->in_eval = false; | ||
| 57 | |||
| 56 | #define SP_INIT(F) F = pecalloc(sizeof(*F), 1, 1); | 58 | #define SP_INIT(F) F = pecalloc(sizeof(*F), 1, 1); |
| 57 | #define SP_INIT_HT(F) \ | 59 | #define SP_INIT_HT(F) \ |
| 58 | F = pemalloc(sizeof(*F), 1); \ | 60 | F = pemalloc(sizeof(*F), 1); \ |
| @@ -60,6 +62,7 @@ PHP_GINIT_FUNCTION(snuffleupagus) { | |||
| 60 | 62 | ||
| 61 | SP_INIT_HT(snuffleupagus_globals->disabled_functions_hook); | 63 | SP_INIT_HT(snuffleupagus_globals->disabled_functions_hook); |
| 62 | SP_INIT_HT(snuffleupagus_globals->sp_internal_functions_hook); | 64 | SP_INIT_HT(snuffleupagus_globals->sp_internal_functions_hook); |
| 65 | SP_INIT_HT(snuffleupagus_globals->sp_eval_filter_functions_hook); | ||
| 63 | 66 | ||
| 64 | SP_INIT(snuffleupagus_globals->config.config_unserialize); | 67 | SP_INIT(snuffleupagus_globals->config.config_unserialize); |
| 65 | SP_INIT(snuffleupagus_globals->config.config_random); | 68 | SP_INIT(snuffleupagus_globals->config.config_random); |
| @@ -73,6 +76,7 @@ PHP_GINIT_FUNCTION(snuffleupagus) { | |||
| 73 | SP_INIT(snuffleupagus_globals->config.config_disabled_functions_ret); | 76 | SP_INIT(snuffleupagus_globals->config.config_disabled_functions_ret); |
| 74 | SP_INIT(snuffleupagus_globals->config.config_cookie); | 77 | SP_INIT(snuffleupagus_globals->config.config_cookie); |
| 75 | SP_INIT(snuffleupagus_globals->config.config_disabled_constructs); | 78 | SP_INIT(snuffleupagus_globals->config.config_disabled_constructs); |
| 79 | SP_INIT(snuffleupagus_globals->config.config_eval); | ||
| 76 | 80 | ||
| 77 | snuffleupagus_globals->config.config_disabled_constructs->construct_include = | 81 | snuffleupagus_globals->config.config_disabled_constructs->construct_include = |
| 78 | sp_list_new(); | 82 | sp_list_new(); |
| @@ -83,6 +87,8 @@ PHP_GINIT_FUNCTION(snuffleupagus) { | |||
| 83 | snuffleupagus_globals->config.config_disabled_functions_ret | 87 | snuffleupagus_globals->config.config_disabled_functions_ret |
| 84 | ->disabled_functions = sp_list_new(); | 88 | ->disabled_functions = sp_list_new(); |
| 85 | snuffleupagus_globals->config.config_cookie->cookies = sp_list_new(); | 89 | snuffleupagus_globals->config.config_cookie->cookies = sp_list_new(); |
| 90 | snuffleupagus_globals->config.config_eval->blacklist = sp_list_new(); | ||
| 91 | snuffleupagus_globals->config.config_eval->whitelist = sp_list_new(); | ||
| 86 | 92 | ||
| 87 | #undef SP_INIT | 93 | #undef SP_INIT |
| 88 | #undef SP_INIT_HT | 94 | #undef SP_INIT_HT |
| @@ -100,6 +106,7 @@ PHP_MSHUTDOWN_FUNCTION(snuffleupagus) { | |||
| 100 | pefree(SNUFFLEUPAGUS_G(F), 1); | 106 | pefree(SNUFFLEUPAGUS_G(F), 1); |
| 101 | 107 | ||
| 102 | FREE_HT(disabled_functions_hook); | 108 | FREE_HT(disabled_functions_hook); |
| 109 | FREE_HT(sp_eval_filter_functions_hook); | ||
| 103 | 110 | ||
| 104 | #undef FREE_HT | 111 | #undef FREE_HT |
| 105 | 112 | ||
| @@ -124,6 +131,8 @@ PHP_MSHUTDOWN_FUNCTION(snuffleupagus) { | |||
| 124 | FREE_LST_DISABLE(config.config_disabled_constructs->construct_include); | 131 | FREE_LST_DISABLE(config.config_disabled_constructs->construct_include); |
| 125 | FREE_LST_DISABLE(config.config_disabled_constructs->construct_eval); | 132 | FREE_LST_DISABLE(config.config_disabled_constructs->construct_eval); |
| 126 | sp_list_free(SNUFFLEUPAGUS_G(config).config_cookie->cookies); | 133 | sp_list_free(SNUFFLEUPAGUS_G(config).config_cookie->cookies); |
| 134 | sp_list_free(SNUFFLEUPAGUS_G(config).config_eval->blacklist); | ||
| 135 | sp_list_free(SNUFFLEUPAGUS_G(config).config_eval->whitelist); | ||
| 127 | 136 | ||
| 128 | #undef FREE_LST_DISABLE | 137 | #undef FREE_LST_DISABLE |
| 129 | 138 | ||
diff --git a/src/sp_config.c b/src/sp_config.c index 4d95062..dc5aae9 100644 --- a/src/sp_config.c +++ b/src/sp_config.c | |||
| @@ -19,6 +19,7 @@ sp_config_tokens const sp_func[] = { | |||
| 19 | {.func = parse_global, .token = SP_TOKEN_GLOBAL}, | 19 | {.func = parse_global, .token = SP_TOKEN_GLOBAL}, |
| 20 | {.func = parse_auto_cookie_secure, .token = SP_TOKEN_AUTO_COOKIE_SECURE}, | 20 | {.func = parse_auto_cookie_secure, .token = SP_TOKEN_AUTO_COOKIE_SECURE}, |
| 21 | {.func = parse_disable_xxe, .token = SP_TOKEN_DISABLE_XXE}, | 21 | {.func = parse_disable_xxe, .token = SP_TOKEN_DISABLE_XXE}, |
| 22 | {.func = parse_eval_filter, .token = SP_TOKEN_EVAL}, | ||
| 22 | {NULL, NULL}}; | 23 | {NULL, NULL}}; |
| 23 | 24 | ||
| 24 | /* Top level keyword parsing */ | 25 | /* Top level keyword parsing */ |
diff --git a/src/sp_config.h b/src/sp_config.h index 2417cf9..a4a4f10 100644 --- a/src/sp_config.h +++ b/src/sp_config.h | |||
| @@ -112,6 +112,12 @@ typedef struct { | |||
| 112 | } sp_disabled_function; | 112 | } sp_disabled_function; |
| 113 | 113 | ||
| 114 | typedef struct { | 114 | typedef struct { |
| 115 | sp_list_node *blacklist; | ||
| 116 | sp_list_node *whitelist; | ||
| 117 | bool simulation; | ||
| 118 | } sp_config_eval; | ||
| 119 | |||
| 120 | typedef struct { | ||
| 115 | sp_list_node *disabled_functions; // list of sp_disabled_function | 121 | sp_list_node *disabled_functions; // list of sp_disabled_function |
| 116 | } sp_config_disabled_functions; | 122 | } sp_config_disabled_functions; |
| 117 | 123 | ||
| @@ -145,6 +151,7 @@ typedef struct { | |||
| 145 | sp_config_global_strict *config_global_strict; | 151 | sp_config_global_strict *config_global_strict; |
| 146 | sp_config_disable_xxe *config_disable_xxe; | 152 | sp_config_disable_xxe *config_disable_xxe; |
| 147 | sp_config_disabled_constructs *config_disabled_constructs; | 153 | sp_config_disabled_constructs *config_disabled_constructs; |
| 154 | sp_config_eval *config_eval; | ||
| 148 | } sp_config; | 155 | } sp_config; |
| 149 | 156 | ||
| 150 | typedef struct { | 157 | typedef struct { |
| @@ -170,6 +177,7 @@ typedef struct { | |||
| 170 | #define SP_TOKEN_UNSERIALIZE_HMAC ".unserialize_hmac" | 177 | #define SP_TOKEN_UNSERIALIZE_HMAC ".unserialize_hmac" |
| 171 | #define SP_TOKEN_UPLOAD_VALIDATION ".upload_validation" | 178 | #define SP_TOKEN_UPLOAD_VALIDATION ".upload_validation" |
| 172 | #define SP_TOKEN_DISABLE_XXE ".disable_xxe" | 179 | #define SP_TOKEN_DISABLE_XXE ".disable_xxe" |
| 180 | #define SP_TOKEN_EVAL ".eval_filter" | ||
| 173 | 181 | ||
| 174 | // common tokens | 182 | // common tokens |
| 175 | #define SP_TOKEN_ENABLE ".enable(" | 183 | #define SP_TOKEN_ENABLE ".enable(" |
| @@ -222,6 +230,10 @@ typedef struct { | |||
| 222 | // upload_validator | 230 | // upload_validator |
| 223 | #define SP_TOKEN_UPLOAD_SCRIPT ".script(" | 231 | #define SP_TOKEN_UPLOAD_SCRIPT ".script(" |
| 224 | 232 | ||
| 233 | // eval blacklist | ||
| 234 | #define SP_TOKEN_EVAL_BLACKLIST ".blacklist(" | ||
| 235 | #define SP_TOKEN_EVAL_WHITELIST ".whitelist(" | ||
| 236 | |||
| 225 | int sp_parse_config(const char *); | 237 | int sp_parse_config(const char *); |
| 226 | int parse_array(sp_disabled_function *); | 238 | int parse_array(sp_disabled_function *); |
| 227 | 239 | ||
diff --git a/src/sp_config_keywords.c b/src/sp_config_keywords.c index 998b692..85e04ab 100644 --- a/src/sp_config_keywords.c +++ b/src/sp_config_keywords.c | |||
| @@ -102,6 +102,25 @@ int parse_global(char *line) { | |||
| 102 | return parse_keywords(sp_config_funcs_global, line); | 102 | return parse_keywords(sp_config_funcs_global, line); |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | int parse_eval_filter(char *line) { | ||
| 106 | char *token; | ||
| 107 | char *rest; | ||
| 108 | sp_config_functions sp_config_funcs[] = { | ||
| 109 | {parse_str, SP_TOKEN_EVAL_BLACKLIST, &rest}, | ||
| 110 | {parse_empty, SP_TOKEN_SIMULATION, | ||
| 111 | &(SNUFFLEUPAGUS_G(config).config_eval->simulation)}, | ||
| 112 | {0}}; | ||
| 113 | int ret = parse_keywords(sp_config_funcs, line); | ||
| 114 | if (0 != ret) { | ||
| 115 | return ret; | ||
| 116 | } | ||
| 117 | |||
| 118 | while ((token = strtok_r(rest, ",", &rest))) { | ||
| 119 | sp_list_insert(SNUFFLEUPAGUS_G(config).config_eval->blacklist, token); | ||
| 120 | } | ||
| 121 | return SUCCESS; | ||
| 122 | } | ||
| 123 | |||
| 105 | int parse_cookie(char *line) { | 124 | int parse_cookie(char *line) { |
| 106 | int ret = 0; | 125 | int ret = 0; |
| 107 | char *samesite = NULL; | 126 | char *samesite = NULL; |
diff --git a/src/sp_config_keywords.h b/src/sp_config_keywords.h index 8286997..d7ea36a 100644 --- a/src/sp_config_keywords.h +++ b/src/sp_config_keywords.h | |||
| @@ -12,5 +12,6 @@ int parse_unserialize(char *line); | |||
| 12 | int parse_readonly_exec(char *line); | 12 | int parse_readonly_exec(char *line); |
| 13 | int parse_disabled_functions(char *line); | 13 | int parse_disabled_functions(char *line); |
| 14 | int parse_upload_validation(char *line); | 14 | int parse_upload_validation(char *line); |
| 15 | int parse_eval_filter(char *line); | ||
| 15 | 16 | ||
| 16 | #endif // __SP_CONFIG_KEYWORDS_H | 17 | #endif // __SP_CONFIG_KEYWORDS_H |
diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index 829f938..45b8954 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c | |||
| @@ -431,8 +431,8 @@ ZEND_FUNCTION(check_disabled_function) { | |||
| 431 | } | 431 | } |
| 432 | 432 | ||
| 433 | orig_handler = zend_hash_str_find_ptr( | 433 | orig_handler = zend_hash_str_find_ptr( |
| 434 | SNUFFLEUPAGUS_G(disabled_functions_hook), current_function_name, | 434 | SNUFFLEUPAGUS_G(disabled_functions_hook), current_function_name, |
| 435 | strlen(current_function_name)); | 435 | strlen(current_function_name)); |
| 436 | orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); | 436 | orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); |
| 437 | if (true == should_drop_on_ret(return_value, execute_data)) { | 437 | if (true == should_drop_on_ret(return_value, execute_data)) { |
| 438 | sp_terminate(); | 438 | sp_terminate(); |
| @@ -460,6 +460,31 @@ static int hook_functions(const sp_list_node* config) { | |||
| 460 | return SUCCESS; | 460 | return SUCCESS; |
| 461 | } | 461 | } |
| 462 | 462 | ||
| 463 | ZEND_FUNCTION(eval_filter_callback) { | ||
| 464 | void (*orig_handler)(INTERNAL_FUNCTION_PARAMETERS); | ||
| 465 | const char* current_function_name = get_active_function_name(TSRMLS_C); | ||
| 466 | |||
| 467 | if (SNUFFLEUPAGUS_G(in_eval) == true) { | ||
| 468 | const char* filename = get_eval_filename(zend_get_executed_filename()); | ||
| 469 | const int line_number = zend_get_executed_lineno(TSRMLS_C); | ||
| 470 | if (1 == SNUFFLEUPAGUS_G(config).config_eval->simulation) { | ||
| 471 | sp_log_msg("eval", SP_LOG_SIMULATION, | ||
| 472 | "A call to %s was tried in eval, in %s:%d, dropping it.", | ||
| 473 | current_function_name, filename, line_number); | ||
| 474 | } else { | ||
| 475 | sp_log_msg("eval", SP_LOG_DROP, | ||
| 476 | "A call to %s was tried in eval, in %s:%d, dropping it.", | ||
| 477 | current_function_name, filename, line_number); | ||
| 478 | sp_terminate(); | ||
| 479 | } | ||
| 480 | } | ||
| 481 | |||
| 482 | orig_handler = zend_hash_str_find_ptr( | ||
| 483 | SNUFFLEUPAGUS_G(sp_eval_filter_functions_hook), current_function_name, | ||
| 484 | strlen(current_function_name)); | ||
| 485 | orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); | ||
| 486 | } | ||
| 487 | |||
| 463 | int hook_disabled_functions(void) { | 488 | int hook_disabled_functions(void) { |
| 464 | TSRMLS_FETCH(); | 489 | TSRMLS_FETCH(); |
| 465 | 490 | ||
| @@ -470,5 +495,16 @@ int hook_disabled_functions(void) { | |||
| 470 | ret |= hook_functions(SNUFFLEUPAGUS_G(config) | 495 | ret |= hook_functions(SNUFFLEUPAGUS_G(config) |
| 471 | .config_disabled_functions_ret->disabled_functions); | 496 | .config_disabled_functions_ret->disabled_functions); |
| 472 | 497 | ||
| 498 | if (NULL != SNUFFLEUPAGUS_G(config).config_eval->blacklist->data) { | ||
| 499 | sp_list_node* it = SNUFFLEUPAGUS_G(config).config_eval->blacklist; | ||
| 500 | |||
| 501 | while (it) { | ||
| 502 | hook_function((char*)it->data, | ||
| 503 | SNUFFLEUPAGUS_G(sp_eval_filter_functions_hook), | ||
| 504 | PHP_FN(eval_filter_callback), false); | ||
| 505 | it = it->next; | ||
| 506 | } | ||
| 507 | } | ||
| 508 | |||
| 473 | return ret; | 509 | return ret; |
| 474 | } | 510 | } |
diff --git a/src/sp_execute.c b/src/sp_execute.c index 7dd0798..a50bfd5 100644 --- a/src/sp_execute.c +++ b/src/sp_execute.c | |||
| @@ -68,6 +68,7 @@ static void sp_execute_ex(zend_execute_data *execute_data) { | |||
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | if (execute_data->func->op_array.type == ZEND_EVAL_CODE) { | 70 | if (execute_data->func->op_array.type == ZEND_EVAL_CODE) { |
| 71 | SNUFFLEUPAGUS_G(in_eval) = true; | ||
| 71 | sp_list_node *config = | 72 | sp_list_node *config = |
| 72 | SNUFFLEUPAGUS_G(config).config_disabled_constructs->construct_eval; | 73 | SNUFFLEUPAGUS_G(config).config_disabled_constructs->construct_eval; |
| 73 | char *filename = get_eval_filename((char *)zend_get_executed_filename()); | 74 | char *filename = get_eval_filename((char *)zend_get_executed_filename()); |
| @@ -86,6 +87,8 @@ static void sp_execute_ex(zend_execute_data *execute_data) { | |||
| 86 | if (true == should_drop_on_ret(execute_data->return_value, execute_data)) { | 87 | if (true == should_drop_on_ret(execute_data->return_value, execute_data)) { |
| 87 | sp_terminate(); | 88 | sp_terminate(); |
| 88 | } | 89 | } |
| 90 | |||
| 91 | SNUFFLEUPAGUS_G(in_eval) = false; | ||
| 89 | } | 92 | } |
| 90 | 93 | ||
| 91 | static int sp_stream_open(const char *filename, zend_file_handle *handle) { | 94 | static int sp_stream_open(const char *filename, zend_file_handle *handle) { |
diff --git a/src/sp_harden_rand.c b/src/sp_harden_rand.c index 3727bef..cb57591 100644 --- a/src/sp_harden_rand.c +++ b/src/sp_harden_rand.c | |||
| @@ -56,9 +56,8 @@ PHP_FUNCTION(sp_rand) { | |||
| 56 | 56 | ||
| 57 | /* call the original `rand` function, | 57 | /* call the original `rand` function, |
| 58 | * since we might no be the only ones to hook it*/ | 58 | * since we might no be the only ones to hook it*/ |
| 59 | orig_handler = | 59 | orig_handler = zend_hash_str_find_ptr( |
| 60 | zend_hash_str_find_ptr(SNUFFLEUPAGUS_G(sp_internal_functions_hook), | 60 | SNUFFLEUPAGUS_G(sp_internal_functions_hook), "rand", strlen("rand")); |
| 61 | "rand", strlen("rand")); | ||
| 62 | orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); | 61 | orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); |
| 63 | 62 | ||
| 64 | random_int_wrapper(INTERNAL_FUNCTION_PARAM_PASSTHRU); | 63 | random_int_wrapper(INTERNAL_FUNCTION_PARAM_PASSTHRU); |
| @@ -70,8 +69,8 @@ PHP_FUNCTION(sp_mt_rand) { | |||
| 70 | /* call the original `mt_rand` function, | 69 | /* call the original `mt_rand` function, |
| 71 | * since we might no be the only ones to hook it*/ | 70 | * since we might no be the only ones to hook it*/ |
| 72 | orig_handler = | 71 | orig_handler = |
| 73 | zend_hash_str_find_ptr(SNUFFLEUPAGUS_G(sp_internal_functions_hook), | 72 | zend_hash_str_find_ptr(SNUFFLEUPAGUS_G(sp_internal_functions_hook), |
| 74 | "mt_rand", strlen("mt_rand")); | 73 | "mt_rand", strlen("mt_rand")); |
| 75 | orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); | 74 | orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); |
| 76 | 75 | ||
| 77 | random_int_wrapper(INTERNAL_FUNCTION_PARAM_PASSTHRU); | 76 | random_int_wrapper(INTERNAL_FUNCTION_PARAM_PASSTHRU); |
diff --git a/src/sp_unserialize.c b/src/sp_unserialize.c index 476bebc..f78b046 100644 --- a/src/sp_unserialize.c +++ b/src/sp_unserialize.c | |||
| @@ -7,7 +7,7 @@ PHP_FUNCTION(sp_serialize) { | |||
| 7 | 7 | ||
| 8 | /* Call the original `serialize` function. */ | 8 | /* Call the original `serialize` function. */ |
| 9 | orig_handler = zend_hash_str_find_ptr( | 9 | orig_handler = zend_hash_str_find_ptr( |
| 10 | SNUFFLEUPAGUS_G(sp_internal_functions_hook), "serialize", 9); | 10 | SNUFFLEUPAGUS_G(sp_internal_functions_hook), "serialize", 9); |
| 11 | orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); | 11 | orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); |
| 12 | 12 | ||
| 13 | /* Compute the HMAC of the textual representation of the serialized data*/ | 13 | /* Compute the HMAC of the textual representation of the serialized data*/ |
diff --git a/src/tests/config/eval_backlist.ini b/src/tests/config/eval_backlist.ini new file mode 100644 index 0000000..1e34b5b --- /dev/null +++ b/src/tests/config/eval_backlist.ini | |||
| @@ -0,0 +1 @@ | |||
| sp.eval_filter.blacklist("strlen"); | |||
diff --git a/src/tests/config/eval_backlist_list.ini b/src/tests/config/eval_backlist_list.ini new file mode 100644 index 0000000..da5650d --- /dev/null +++ b/src/tests/config/eval_backlist_list.ini | |||
| @@ -0,0 +1 @@ | |||
| sp.eval_filter.blacklist("strcmp,strlen"); | |||
diff --git a/src/tests/config/eval_backlist_simulation.ini b/src/tests/config/eval_backlist_simulation.ini new file mode 100644 index 0000000..fafebd5 --- /dev/null +++ b/src/tests/config/eval_backlist_simulation.ini | |||
| @@ -0,0 +1 @@ | |||
| sp.eval_filter.blacklist("strlen").simulation(); | |||
diff --git a/src/tests/eval_backlist.phpt b/src/tests/eval_backlist.phpt new file mode 100644 index 0000000..20b2c92 --- /dev/null +++ b/src/tests/eval_backlist.phpt | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | --TEST-- | ||
| 2 | Eval blacklist | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php if (!extension_loaded("snuffleupagus")) die "skip"; ?> | ||
| 5 | --INI-- | ||
| 6 | sp.configuration_file={PWD}/config/eval_backlist.ini | ||
| 7 | --FILE-- | ||
| 8 | <?php | ||
| 9 | $a = strlen("1337 1337 1337"); | ||
| 10 | echo "Outside of eval: $a\n"; | ||
| 11 | eval('$a = strlen("1234");'); | ||
| 12 | echo "After eval: $a\n"; | ||
| 13 | ?> | ||
| 14 | --EXPECTF-- | ||
| 15 | Outside of eval: 14 | ||
| 16 | [snuffleupagus][0.0.0.0][eval][drop] A call to strlen was tried in eval, in%atests/eval_backlist.php:1, dropping it. | ||
diff --git a/src/tests/eval_backlist_list.phpt b/src/tests/eval_backlist_list.phpt new file mode 100644 index 0000000..b1c7bfd --- /dev/null +++ b/src/tests/eval_backlist_list.phpt | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | --TEST-- | ||
| 2 | Eval blacklist - with a list of functions | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php if (!extension_loaded("snuffleupagus")) die "skip"; ?> | ||
| 5 | --INI-- | ||
| 6 | sp.configuration_file={PWD}/config/eval_backlist_list.ini | ||
| 7 | --FILE-- | ||
| 8 | <?php | ||
| 9 | $a = strlen("1337 1337 1337"); | ||
| 10 | echo "Outside of eval: $a\n"; | ||
| 11 | eval('$a = strlen("1234");'); | ||
| 12 | echo "After eval: $a\n"; | ||
| 13 | ?> | ||
| 14 | --EXPECTF-- | ||
| 15 | Outside of eval: 14 | ||
| 16 | [snuffleupagus][0.0.0.0][eval][drop] A call to strlen was tried in eval, in %a/tests/eval_backlist_list.php:1, dropping it. | ||
diff --git a/src/tests/eval_backlist_simulation.phpt b/src/tests/eval_backlist_simulation.phpt new file mode 100644 index 0000000..ddeae60 --- /dev/null +++ b/src/tests/eval_backlist_simulation.phpt | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | --TEST-- | ||
| 2 | Eval blacklist | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php if (!extension_loaded("snuffleupagus")) die "skip"; ?> | ||
| 5 | --INI-- | ||
| 6 | sp.configuration_file={PWD}/config/eval_backlist_simulation.ini | ||
| 7 | --FILE-- | ||
| 8 | <?php | ||
| 9 | $a = strlen("1337 1337 1337"); | ||
| 10 | echo "Outside of eval: $a\n"; | ||
| 11 | eval('$a = strlen("1234");'); | ||
| 12 | echo "After eval: $a\n"; | ||
| 13 | ?> | ||
| 14 | --EXPECTF-- | ||
| 15 | Outside of eval: 14 | ||
| 16 | [snuffleupagus][0.0.0.0][eval][simulation] A call to strlen was tried in eval, in %a/tests/eval_backlist_simulation.php:1, dropping it. | ||
| 17 | After eval: 4 | ||
diff --git a/src/tests/nested_eval_blacklist.phpt b/src/tests/nested_eval_blacklist.phpt new file mode 100644 index 0000000..b12bf93 --- /dev/null +++ b/src/tests/nested_eval_blacklist.phpt | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | --TEST-- | ||
| 2 | Eval blacklist - nested eval | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php if (!extension_loaded("snuffleupagus")) die "skip"; ?> | ||
| 5 | --INI-- | ||
| 6 | sp.configuration_file={PWD}/config/eval_backlist.ini | ||
| 7 | --FILE-- | ||
| 8 | <?php | ||
| 9 | $a = strlen("1337 1337 1337"); | ||
| 10 | echo "Outside of eval: $a\n"; | ||
| 11 | eval( | ||
| 12 | "echo 'Inception lvl 1...\n'; | ||
| 13 | eval( | ||
| 14 | 'echo \"Inception lvl 2...\n\"; | ||
| 15 | eval( | ||
| 16 | \"echo \'Inception lvl 3...\n\'; | ||
| 17 | strlen(\'Limbo!\'); | ||
| 18 | \"); | ||
| 19 | '); | ||
| 20 | "); | ||
| 21 | echo "After eval: $a\n"; | ||
| 22 | ?> | ||
| 23 | --EXPECTF-- | ||
| 24 | Outside of eval: 14 | ||
| 25 | Inception lvl 1... | ||
| 26 | Inception lvl 2... | ||
| 27 | Inception lvl 3... | ||
| 28 | [snuffleupagus][0.0.0.0][eval][drop] A call to strlen was tried in eval, in %a/tests/nested_eval_blacklist.php(5) : eval()'d code(4) : eval()'d code:3, dropping it. | ||
