summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorxXx-caillou-xXx2018-07-13 11:38:51 +0200
committerjvoisin2018-07-13 09:38:51 +0000
commit94649dee9e8b8b6c6c28b79d565ae7b388e3d6d9 (patch)
tree106df2ad6824ec1c352fd57f577372778e64385b /src
parent7963580d72a358975133f86f01de2d2eab08ba38 (diff)
Allow rules matching on echo and print
Diffstat (limited to 'src')
-rw-r--r--src/snuffleupagus.c7
-rw-r--r--src/sp_disabled_functions.c42
-rw-r--r--src/sp_disabled_functions.h3
-rw-r--r--src/tests/config/disabled_function_echo.ini2
-rw-r--r--src/tests/disabled_function_echo.phpt18
-rw-r--r--src/tests/disabled_function_echo_2.phpt14
-rw-r--r--src/tests/disabled_function_echo_local_var.phpt20
7 files changed, 101 insertions, 5 deletions
diff --git a/src/snuffleupagus.c b/src/snuffleupagus.c
index edca185..ad1d0a9 100644
--- a/src/snuffleupagus.c
+++ b/src/snuffleupagus.c
@@ -261,6 +261,13 @@ static PHP_INI_MH(OnUpdateConfiguration) {
261 // This is needed to implement the global strict mode 261 // This is needed to implement the global strict mode
262 CG(compiler_options) |= ZEND_COMPILE_HANDLE_OP_ARRAY; 262 CG(compiler_options) |= ZEND_COMPILE_HANDLE_OP_ARRAY;
263 } 263 }
264 if (zend_hash_str_find(SNUFFLEUPAGUS_G(config).config_disabled_functions_hooked,
265 "echo", strlen("echo")) ||
266 zend_hash_str_find(SNUFFLEUPAGUS_G(config).config_disabled_functions_ret_hooked,
267 "echo", strlen("echo"))) {
268 zend_write_default = zend_write;
269 zend_write = hook_echo;
270 }
264 271
265 SNUFFLEUPAGUS_G(config).hook_execute = 272 SNUFFLEUPAGUS_G(config).hook_execute =
266 SNUFFLEUPAGUS_G(config).config_disabled_functions_reg->disabled_functions || 273 SNUFFLEUPAGUS_G(config).config_disabled_functions_reg->disabled_functions ||
diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c
index 14783f6..f266951 100644
--- a/src/sp_disabled_functions.c
+++ b/src/sp_disabled_functions.c
@@ -236,13 +236,15 @@ static bool check_is_builtin_name(
236 return (zend_string_equals_literal(config_node->function, "include") || 236 return (zend_string_equals_literal(config_node->function, "include") ||
237 zend_string_equals_literal(config_node->function, "include_once") || 237 zend_string_equals_literal(config_node->function, "include_once") ||
238 zend_string_equals_literal(config_node->function, "require") || 238 zend_string_equals_literal(config_node->function, "require") ||
239 zend_string_equals_literal(config_node->function, "require_once")); 239 zend_string_equals_literal(config_node->function, "require_once") ||
240 zend_string_equals_literal(config_node->function, "echo"));
240 } 241 }
241 if (config_node->r_function) { 242 if (config_node->r_function) {
242 return (sp_is_regexp_matching(config_node->r_function, "include") || 243 return (sp_is_regexp_matching(config_node->r_function, "include") ||
243 sp_is_regexp_matching(config_node->r_function, "include_once") || 244 sp_is_regexp_matching(config_node->r_function, "include_once") ||
244 sp_is_regexp_matching(config_node->r_function, "require") || 245 sp_is_regexp_matching(config_node->r_function, "require") ||
245 sp_is_regexp_matching(config_node->r_function, "require_once")); 246 sp_is_regexp_matching(config_node->r_function, "require_once") ||
247 sp_is_regexp_matching(config_node->r_function, "echo"));
246 } 248 }
247 return false; 249 return false;
248} 250}
@@ -383,7 +385,12 @@ bool should_disable(zend_execute_data* execute_data,
383 } 385 }
384 386
385 if (config_node->r_value || config_node->value) { 387 if (config_node->r_value || config_node->value) {
386 if (check_is_builtin_name(config_node)) { 388 if (check_is_builtin_name(config_node) &&
389 !config_node->var &&
390 !config_node->param &&
391 !config_node->r_param &&
392 !config_node->key &&
393 !config_node->r_key) {
387 if (false == is_param_matching(execute_data, config_node, builtin_param, 394 if (false == is_param_matching(execute_data, config_node, builtin_param,
388 &arg_name, builtin_param_name, 395 &arg_name, builtin_param_name,
389 &arg_value_str)) { 396 &arg_value_str)) {
@@ -566,8 +573,14 @@ static int hook_functions(HashTable* to_hook_ht, HashTable* hooked_ht) {
566 if (!HOOK_FUNCTION(ZSTR_VAL(key), disabled_functions_hook, 573 if (!HOOK_FUNCTION(ZSTR_VAL(key), disabled_functions_hook,
567 PHP_FN(check_disabled_function)) || 574 PHP_FN(check_disabled_function)) ||
568 check_is_builtin_name(((sp_list_node*)Z_PTR_P(value))->data)) { 575 check_is_builtin_name(((sp_list_node*)Z_PTR_P(value))->data)) {
569 zend_symtable_add_new(hooked_ht, key, value); 576 if (zend_string_equals_literal(key, "echo") ||
570 zend_hash_del(to_hook_ht, key); 577 zend_string_equals_literal(key, "print")) {
578 zend_hash_str_add_new(hooked_ht, "echo", strlen("echo"), value);
579 zend_hash_del(to_hook_ht, key);
580 } else {
581 zend_symtable_add_new(hooked_ht, key, value);
582 zend_hash_del(to_hook_ht, key);
583 }
571 } 584 }
572 } 585 }
573 ZEND_HASH_FOREACH_END(); 586 ZEND_HASH_FOREACH_END();
@@ -648,3 +661,22 @@ int hook_disabled_functions(void) {
648 } 661 }
649 return ret; 662 return ret;
650} 663}
664
665zend_write_func_t zend_write_default = NULL;
666
667int hook_echo(const char* str, size_t str_length) {
668 zend_string* zs = zend_string_init(str, str_length, 0);
669
670 bool ret = should_disable_ht(
671 EG(current_execute_data), "echo", zs, NULL,
672 SNUFFLEUPAGUS_G(config).config_disabled_functions_reg->disabled_functions,
673 SNUFFLEUPAGUS_G(config).config_disabled_functions_hooked);
674
675 zend_string_release(zs);
676
677 if (ret) {
678 sp_terminate();
679 }
680
681 return zend_write_default(str, str_length);
682}
diff --git a/src/sp_disabled_functions.h b/src/sp_disabled_functions.h
index 4e795a1..83b1551 100644
--- a/src/sp_disabled_functions.h
+++ b/src/sp_disabled_functions.h
@@ -1,7 +1,10 @@
1#ifndef __SP_DISABLE_FUNCTIONS_H 1#ifndef __SP_DISABLE_FUNCTIONS_H
2#define __SP_DISABLE_FUNCTIONS_H 2#define __SP_DISABLE_FUNCTIONS_H
3 3
4extern zend_write_func_t zend_write_default;
5
4int hook_disabled_functions(); 6int hook_disabled_functions();
7int hook_echo(const char*, size_t);
5bool should_disable(zend_execute_data *, const char *, const zend_string *, 8bool should_disable(zend_execute_data *, const char *, const zend_string *,
6 const char *, const sp_list_node *, const zend_string *); 9 const char *, const sp_list_node *, const zend_string *);
7bool should_disable_ht(zend_execute_data *, const char *, const zend_string *, 10bool should_disable_ht(zend_execute_data *, const char *, const zend_string *,
diff --git a/src/tests/config/disabled_function_echo.ini b/src/tests/config/disabled_function_echo.ini
new file mode 100644
index 0000000..39bc5e3
--- /dev/null
+++ b/src/tests/config/disabled_function_echo.ini
@@ -0,0 +1,2 @@
1sp.disable_function.function("echo").var("$abc").value("123").drop();
2sp.disable_function.function("echo").value("oops").drop();
diff --git a/src/tests/disabled_function_echo.phpt b/src/tests/disabled_function_echo.phpt
new file mode 100644
index 0000000..a884e4a
--- /dev/null
+++ b/src/tests/disabled_function_echo.phpt
@@ -0,0 +1,18 @@
1--TEST--
2Echo hooking
3--SKIPIF--
4<?php if (!extension_loaded("snuffleupagus")) die "skip"; ?>
5--INI--
6sp.configuration_file={PWD}/config/disabled_function_echo.ini
7--FILE--
8<?php
9function test($a) {
10 print "$a";
11}
12echo "qwe";
13test("rty");
14test("oops");
15?>
16--CLEAN--
17--EXPECTF--
18qwerty[snuffleupagus][0.0.0.0][disabled_function][drop] Aborted execution on call of the function 'echo' in %a/tests/disabled_function_echo.php:3.
diff --git a/src/tests/disabled_function_echo_2.phpt b/src/tests/disabled_function_echo_2.phpt
new file mode 100644
index 0000000..20dbee4
--- /dev/null
+++ b/src/tests/disabled_function_echo_2.phpt
@@ -0,0 +1,14 @@
1--TEST--
2Echo hooking
3--SKIPIF--
4<?php if (!extension_loaded("snuffleupagus")) die "skip"; ?>
5--INI--
6sp.configuration_file={PWD}/config/disabled_function_echo.ini
7--FILE--
8<?php
9echo "qwe";
10echo "1", "oops";
11?>
12--CLEAN--
13--EXPECTF--
14qwe1[snuffleupagus][0.0.0.0][disabled_function][drop] Aborted execution on call of the function 'echo' in %a/tests/disabled_function_echo_2.php:3.
diff --git a/src/tests/disabled_function_echo_local_var.phpt b/src/tests/disabled_function_echo_local_var.phpt
new file mode 100644
index 0000000..bfa3c8c
--- /dev/null
+++ b/src/tests/disabled_function_echo_local_var.phpt
@@ -0,0 +1,20 @@
1--TEST--
2Echo hooking
3--SKIPIF--
4<?php if (!extension_loaded("snuffleupagus")) die "skip"; ?>
5--INI--
6sp.configuration_file={PWD}/config/disabled_function_echo.ini
7--FILE--
8<?php
9function test() {
10 print "3\n";
11}
12$abc = 1;
13test();
14$abc = 123;
15test();
16?>
17--CLEAN--
18--EXPECTF--
193
20[snuffleupagus][0.0.0.0][disabled_function][drop] Aborted execution on call of the function 'echo' in %a/tests/disabled_function_echo_local_var.php:3.