diff options
| author | jvoisin | 2017-10-10 18:11:31 +0200 |
|---|---|---|
| committer | jvoisin | 2017-10-18 15:27:21 +0200 |
| commit | fe43991e3dc6c46e2781d21369f5e268de7baef9 (patch) | |
| tree | 027471bdcce37397c4b39b6f9fbf252104a2ebde | |
| parent | e8d255e5cef8949256d3290b2d8fd22de9428a83 (diff) | |
Implement match on arguments position
| -rw-r--r-- | src/sp_config.h | 2 | ||||
| -rw-r--r-- | src/sp_config_keywords.c | 7 | ||||
| -rw-r--r-- | src/sp_disabled_functions.c | 14 | ||||
| -rw-r--r-- | src/tests/config/disabled_functions_pos.ini | 1 | ||||
| -rw-r--r-- | src/tests/disabled_functions_param_pos.phpt | 12 |
5 files changed, 32 insertions, 4 deletions
diff --git a/src/sp_config.h b/src/sp_config.h index 0877ebb..c005206 100644 --- a/src/sp_config.h +++ b/src/sp_config.h | |||
| @@ -77,6 +77,7 @@ typedef struct { | |||
| 77 | char *param; | 77 | char *param; |
| 78 | pcre *r_param; | 78 | pcre *r_param; |
| 79 | sp_php_type param_type; | 79 | sp_php_type param_type; |
| 80 | int pos; | ||
| 80 | 81 | ||
| 81 | char *ret; | 82 | char *ret; |
| 82 | pcre *r_ret; | 83 | pcre *r_ret; |
| @@ -183,6 +184,7 @@ typedef struct { | |||
| 183 | #define SP_TOKEN_RET_TYPE ".ret_type(" | 184 | #define SP_TOKEN_RET_TYPE ".ret_type(" |
| 184 | #define SP_TOKEN_VALUE ".value(" | 185 | #define SP_TOKEN_VALUE ".value(" |
| 185 | #define SP_TOKEN_VALUE_REGEXP ".value_r(" | 186 | #define SP_TOKEN_VALUE_REGEXP ".value_r(" |
| 187 | #define SP_TOKEN_VALUE_ARG_POS ".pos(" | ||
| 186 | 188 | ||
| 187 | // cookies encryption | 189 | // cookies encryption |
| 188 | #define SP_TOKEN_NAME ".cookie(" | 190 | #define SP_TOKEN_NAME ".cookie(" |
diff --git a/src/sp_config_keywords.c b/src/sp_config_keywords.c index 29f1bfc..1f48852 100644 --- a/src/sp_config_keywords.c +++ b/src/sp_config_keywords.c | |||
| @@ -144,7 +144,9 @@ int parse_cookie_encryption(char *line) { | |||
| 144 | int parse_disabled_functions(char *line) { | 144 | int parse_disabled_functions(char *line) { |
| 145 | int ret = 0; | 145 | int ret = 0; |
| 146 | bool enable = true, disable = false; | 146 | bool enable = true, disable = false; |
| 147 | char *pos = NULL; | ||
| 147 | sp_disabled_function *df = pecalloc(sizeof(*df), 1, 1); | 148 | sp_disabled_function *df = pecalloc(sizeof(*df), 1, 1); |
| 149 | df->pos = -1; | ||
| 148 | 150 | ||
| 149 | sp_config_functions sp_config_funcs_disabled_functions[] = { | 151 | sp_config_functions sp_config_funcs_disabled_functions[] = { |
| 150 | {parse_empty, SP_TOKEN_ENABLE, &(enable)}, | 152 | {parse_empty, SP_TOKEN_ENABLE, &(enable)}, |
| @@ -169,6 +171,7 @@ int parse_disabled_functions(char *line) { | |||
| 169 | {parse_regexp, SP_TOKEN_RET_REGEXP, &(df->r_ret)}, | 171 | {parse_regexp, SP_TOKEN_RET_REGEXP, &(df->r_ret)}, |
| 170 | {parse_php_type, SP_TOKEN_RET_TYPE, &(df->ret_type)}, | 172 | {parse_php_type, SP_TOKEN_RET_TYPE, &(df->ret_type)}, |
| 171 | {parse_str, SP_TOKEN_LOCAL_VAR, &(df->var)}, | 173 | {parse_str, SP_TOKEN_LOCAL_VAR, &(df->var)}, |
| 174 | {parse_str, SP_TOKEN_VALUE_ARG_POS, &(pos)}, | ||
| 172 | {0}}; | 175 | {0}}; |
| 173 | 176 | ||
| 174 | ret = parse_keywords(sp_config_funcs_disabled_functions, line); | 177 | ret = parse_keywords(sp_config_funcs_disabled_functions, line); |
| @@ -233,6 +236,10 @@ int parse_disabled_functions(char *line) { | |||
| 233 | return -1; | 236 | return -1; |
| 234 | } | 237 | } |
| 235 | 238 | ||
| 239 | if (pos) { | ||
| 240 | df->pos = atoi(pos) > 128 ? 128: atoi(pos); // FIXME do the strtol dance | ||
| 241 | } | ||
| 242 | |||
| 236 | if (df->function) { | 243 | if (df->function) { |
| 237 | df->functions_list = parse_functions_list(df->function); | 244 | df->functions_list = parse_functions_list(df->function); |
| 238 | } | 245 | } |
diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index c8c723a..b05d949 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c | |||
| @@ -178,11 +178,17 @@ bool should_disable(zend_execute_data* execute_data) { | |||
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | /* Check if we filter on parameter value*/ | 180 | /* Check if we filter on parameter value*/ |
| 181 | if (config_node->param || config_node->r_param) { | 181 | if (config_node->param || config_node->r_param || (config_node->pos != -1)) { |
| 182 | const unsigned int nb_param = execute_data->func->common.num_args; | 182 | unsigned int nb_param = execute_data->func->common.num_args; |
| 183 | bool arg_matched = false; | 183 | bool arg_matched = false; |
| 184 | int i = 0; | ||
| 184 | 185 | ||
| 185 | for (unsigned int i = 0; i < nb_param; i++) { | 186 | if (config_node->pos != -1) {//&& nb_param <= config_node->pos) { |
| 187 | i = config_node->pos; | ||
| 188 | nb_param = (config_node->pos) + 1; | ||
| 189 | } | ||
| 190 | |||
| 191 | for (; i < nb_param; i++) { | ||
| 186 | arg_matched = false; | 192 | arg_matched = false; |
| 187 | if (ZEND_USER_CODE(execute_data->func->type)) { // yay consistency | 193 | if (ZEND_USER_CODE(execute_data->func->type)) { // yay consistency |
| 188 | arg_name = ZSTR_VAL(execute_data->func->common.arg_info[i].name); | 194 | arg_name = ZSTR_VAL(execute_data->func->common.arg_info[i].name); |
| @@ -197,7 +203,7 @@ bool should_disable(zend_execute_data* execute_data) { | |||
| 197 | (true == is_regexp_matching(config_node->r_param, arg_name)); | 203 | (true == is_regexp_matching(config_node->r_param, arg_name)); |
| 198 | 204 | ||
| 199 | /* This is the parameter name we're looking for. */ | 205 | /* This is the parameter name we're looking for. */ |
| 200 | if (true == arg_matching || true == pcre_matching) { | 206 | if (true == arg_matching || true == pcre_matching || (config_node->pos != -1)) { |
| 201 | zval* arg_value = ZEND_CALL_VAR_NUM(execute_data, i); | 207 | zval* arg_value = ZEND_CALL_VAR_NUM(execute_data, i); |
| 202 | 208 | ||
| 203 | if (config_node->param_type) { // Are we matching on the `type`? | 209 | if (config_node->param_type) { // Are we matching on the `type`? |
diff --git a/src/tests/config/disabled_functions_pos.ini b/src/tests/config/disabled_functions_pos.ini new file mode 100644 index 0000000..81a524e --- /dev/null +++ b/src/tests/config/disabled_functions_pos.ini | |||
| @@ -0,0 +1 @@ | |||
| sp.disable_functions.function("system").pos("0").value("id").drop(); | |||
diff --git a/src/tests/disabled_functions_param_pos.phpt b/src/tests/disabled_functions_param_pos.phpt new file mode 100644 index 0000000..de578b2 --- /dev/null +++ b/src/tests/disabled_functions_param_pos.phpt | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | --TEST-- | ||
| 2 | Disable functions - match on argument's position | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php if (!extension_loaded("snuffleupagus")) die "skip"; ?> | ||
| 5 | --INI-- | ||
| 6 | sp.configuration_file={PWD}/config/disabled_functions_pos.ini | ||
| 7 | --FILE-- | ||
| 8 | <?php | ||
| 9 | system("id"); | ||
| 10 | ?> | ||
| 11 | --EXPECTF-- | ||
| 12 | [snuffleupagus][0.0.0.0][disabled_function][drop] The call to the function 'system' in %a/disabled_functions_param_pos.php:%d has been disabled, because its argument 'command' content (id) matched a rule. | ||
