summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjvoisin2017-10-10 18:11:31 +0200
committerjvoisin2017-10-18 15:27:21 +0200
commitfe43991e3dc6c46e2781d21369f5e268de7baef9 (patch)
tree027471bdcce37397c4b39b6f9fbf252104a2ebde
parente8d255e5cef8949256d3290b2d8fd22de9428a83 (diff)
Implement match on arguments position
-rw-r--r--src/sp_config.h2
-rw-r--r--src/sp_config_keywords.c7
-rw-r--r--src/sp_disabled_functions.c14
-rw-r--r--src/tests/config/disabled_functions_pos.ini1
-rw-r--r--src/tests/disabled_functions_param_pos.phpt12
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) {
144int parse_disabled_functions(char *line) { 144int 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--
2Disable functions - match on argument's position
3--SKIPIF--
4<?php if (!extension_loaded("snuffleupagus")) die "skip"; ?>
5--INI--
6sp.configuration_file={PWD}/config/disabled_functions_pos.ini
7--FILE--
8<?php
9system("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.