summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Fuhrmannek2014-09-25 17:24:39 +0200
committerBen Fuhrmannek2014-09-25 17:24:39 +0200
commit594c8df58c6f7f9b9610c7f0fd11da08a532de98 (patch)
tree7f1286f40af4133aa01035ec9303e1a9aabccd2e
parent8f2433d78347b2f1542e95652fa74d38346fb6ec (diff)
array index whitelist/blacklist
-rw-r--r--execute.c1
-rw-r--r--ifilter.c40
-rw-r--r--php_suhosin.h2
-rw-r--r--suhosin.c2
-rw-r--r--tests/filter/input_filter_request_array_index_blacklist.phpt53
-rw-r--r--tests/filter/input_filter_request_array_index_whitelist.phpt51
6 files changed, 147 insertions, 2 deletions
diff --git a/execute.c b/execute.c
index 560d8f5..a27d82f 100644
--- a/execute.c
+++ b/execute.c
@@ -415,7 +415,6 @@ static void suhosin_execute_ex(zend_op_array *op_array, int zo, long dummy TSRML
415 SUHOSIN_G(att_get_vars)-SUHOSIN_G(cur_get_vars), 415 SUHOSIN_G(att_get_vars)-SUHOSIN_G(cur_get_vars),
416 SUHOSIN_G(att_post_vars)-SUHOSIN_G(cur_post_vars), 416 SUHOSIN_G(att_post_vars)-SUHOSIN_G(cur_post_vars),
417 SUHOSIN_G(att_cookie_vars)-SUHOSIN_G(cur_cookie_vars)); 417 SUHOSIN_G(att_cookie_vars)-SUHOSIN_G(cur_cookie_vars));
418
419 } 418 }
420 419
421 if (!SUHOSIN_G(simulation) && SUHOSIN_G(filter_action)) { 420 if (!SUHOSIN_G(simulation) && SUHOSIN_G(filter_action)) {
diff --git a/ifilter.c b/ifilter.c
index 48b62c7..4ea846f 100644
--- a/ifilter.c
+++ b/ifilter.c
@@ -41,6 +41,26 @@ static size_t strnlen(const char *s, size_t maxlen) {
41} 41}
42#endif 42#endif
43 43
44static size_t strnspn(const char *input, size_t n, const char *accept)
45{
46 size_t count = 0;
47 for (; *input != '\0' && count < n; input++, count++) {
48 if (strchr(accept, *input) == NULL)
49 break;
50 }
51 return count;
52}
53
54static size_t strncspn(const char *input, size_t n, const char *reject)
55{
56 size_t count = 0;
57 for (; *input != '\0' && count < n; input++, count++) {
58 if (strchr(reject, *input) != NULL)
59 break;
60 }
61 return count;
62}
63
44 64
45/* {{{ normalize_varname 65/* {{{ normalize_varname
46 */ 66 */
@@ -524,7 +544,8 @@ unsigned int suhosin_input_filter(int arg, char *var, char **val, unsigned int v
524 } 544 }
525 545
526 index_length = index_end - index; 546 index_length = index_end - index;
527 547
548 /* max. array index length */
528 if (SUHOSIN_G(max_array_index_length) && SUHOSIN_G(max_array_index_length) < index_length) { 549 if (SUHOSIN_G(max_array_index_length) && SUHOSIN_G(max_array_index_length) < index_length) {
529 suhosin_log(S_VARS, "configured request variable array index length limit exceeded - dropped variable '%s'", var); 550 suhosin_log(S_VARS, "configured request variable array index length limit exceeded - dropped variable '%s'", var);
530 if (!SUHOSIN_G(simulation)) { 551 if (!SUHOSIN_G(simulation)) {
@@ -558,6 +579,23 @@ unsigned int suhosin_input_filter(int arg, char *var, char **val, unsigned int v
558 break; 579 break;
559 } 580 }
560 581
582 /* index whitelist/blacklist */
583 if (SUHOSIN_G(array_index_whitelist) && *(SUHOSIN_G(array_index_whitelist))) {
584 if (strnspn(index, index_length, SUHOSIN_G(array_index_whitelist)) != index_length) {
585 suhosin_log(S_VARS, "array index contains not whitelisted characters - dropped variable '%s'", var);
586 if (!SUHOSIN_G(simulation)) {
587 return 0;
588 }
589 }
590 } else if (SUHOSIN_G(array_index_blacklist) && *(SUHOSIN_G(array_index_blacklist))) {
591 if (strncspn(index, index_length, SUHOSIN_G(array_index_blacklist)) != index_length) {
592 suhosin_log(S_VARS, "array index contains blacklisted characters - dropped variable '%s'", var);
593 if (!SUHOSIN_G(simulation)) {
594 return 0;
595 }
596 }
597 }
598
561 index = strchr(index, '['); 599 index = strchr(index, '[');
562 } 600 }
563 601
diff --git a/php_suhosin.h b/php_suhosin.h
index d567877..8877e53 100644
--- a/php_suhosin.h
+++ b/php_suhosin.h
@@ -208,6 +208,8 @@ ZEND_BEGIN_MODULE_GLOBALS(suhosin)
208 long max_value_length; 208 long max_value_length;
209 long max_array_depth; 209 long max_array_depth;
210 long max_array_index_length; 210 long max_array_index_length;
211 char* array_index_whitelist;
212 char* array_index_blacklist;
211 zend_bool disallow_nul; 213 zend_bool disallow_nul;
212 zend_bool disallow_ws; 214 zend_bool disallow_ws;
213/* cookie variables */ 215/* cookie variables */
diff --git a/suhosin.c b/suhosin.c
index fc84a94..4a965ac 100644
--- a/suhosin.c
+++ b/suhosin.c
@@ -790,6 +790,8 @@ PHP_INI_BEGIN()
790 STD_PHP_INI_ENTRY("suhosin.request.max_array_depth", "50", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestLong, max_array_depth, zend_suhosin_globals, suhosin_globals) 790 STD_PHP_INI_ENTRY("suhosin.request.max_array_depth", "50", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestLong, max_array_depth, zend_suhosin_globals, suhosin_globals)
791 STD_PHP_INI_ENTRY("suhosin.request.max_totalname_length", "256", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestLong, max_totalname_length, zend_suhosin_globals, suhosin_globals) 791 STD_PHP_INI_ENTRY("suhosin.request.max_totalname_length", "256", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestLong, max_totalname_length, zend_suhosin_globals, suhosin_globals)
792 STD_PHP_INI_ENTRY("suhosin.request.max_array_index_length", "64", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestLong, max_array_index_length, zend_suhosin_globals, suhosin_globals) 792 STD_PHP_INI_ENTRY("suhosin.request.max_array_index_length", "64", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestLong, max_array_index_length, zend_suhosin_globals, suhosin_globals)
793 STD_PHP_INI_ENTRY("suhosin.request.array_index_whitelist", "", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateString, array_index_whitelist, zend_suhosin_globals, suhosin_globals)
794 STD_PHP_INI_ENTRY("suhosin.request.array_index_blacklist", "", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateString, array_index_blacklist, zend_suhosin_globals, suhosin_globals)
793 STD_PHP_INI_ENTRY("suhosin.request.disallow_nul", "1", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestBool, disallow_nul, zend_suhosin_globals, suhosin_globals) 795 STD_PHP_INI_ENTRY("suhosin.request.disallow_nul", "1", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestBool, disallow_nul, zend_suhosin_globals, suhosin_globals)
794 STD_PHP_INI_ENTRY("suhosin.request.disallow_ws", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestBool, disallow_ws, zend_suhosin_globals, suhosin_globals) 796 STD_PHP_INI_ENTRY("suhosin.request.disallow_ws", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestBool, disallow_ws, zend_suhosin_globals, suhosin_globals)
795 797
diff --git a/tests/filter/input_filter_request_array_index_blacklist.phpt b/tests/filter/input_filter_request_array_index_blacklist.phpt
new file mode 100644
index 0000000..01d551f
--- /dev/null
+++ b/tests/filter/input_filter_request_array_index_blacklist.phpt
@@ -0,0 +1,53 @@
1--TEST--
2suhosin input filter (suhosin.request.array_index_blacklist)
3--INI--
4suhosin.log.syslog=0
5suhosin.log.sapi=0
6suhosin.log.stdout=511
7suhosin.log.script=0
8suhosin.request.array_index_blacklist="=ABC%{}\\$;"
9--SKIPIF--
10<?php include('skipif.inc'); ?>
11--COOKIE--
12var1[aaa]=1;var2[bbB]=1;var3[ccc][ccC]=1
13--GET--
14var1[aaa]=1&var2[bbB]=1&var3[ccc][ccC]=1
15--POST--
16var1[aaa]=1&var2[bbB]=1&var3[ccc][ccC]=1
17--FILE--
18<?php
19var_dump(ini_get("suhosin.request.array_index_blacklist"));
20var_dump($_GET);
21var_dump($_POST);
22var_dump($_COOKIE);
23?>
24--EXPECTF--
25string(10) "=ABC%{}\$;"
26array(1) {
27 ["var1"]=>
28 array(1) {
29 ["aaa"]=>
30 string(1) "1"
31 }
32}
33array(1) {
34 ["var1"]=>
35 array(1) {
36 ["aaa"]=>
37 string(1) "1"
38 }
39}
40array(1) {
41 ["var1"]=>
42 array(1) {
43 ["aaa"]=>
44 string(1) "1"
45 }
46}
47ALERT - array index contains blacklisted characters - dropped variable 'var2[bbB]' (attacker 'REMOTE_ADDR not set', file '%s')
48ALERT - array index contains blacklisted characters - dropped variable 'var3[ccc][ccC]' (attacker 'REMOTE_ADDR not set', file '%s')
49ALERT - array index contains blacklisted characters - dropped variable 'var2[bbB]' (attacker 'REMOTE_ADDR not set', file '%s')
50ALERT - array index contains blacklisted characters - dropped variable 'var3[ccc][ccC]' (attacker 'REMOTE_ADDR not set', file '%s')
51ALERT - array index contains blacklisted characters - dropped variable 'var2[bbB]' (attacker 'REMOTE_ADDR not set', file '%s')
52ALERT - array index contains blacklisted characters - dropped variable 'var3[ccc][ccC]' (attacker 'REMOTE_ADDR not set', file '%s')
53ALERT - dropped 6 request variables - (2 in GET, 2 in POST, 2 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s')
diff --git a/tests/filter/input_filter_request_array_index_whitelist.phpt b/tests/filter/input_filter_request_array_index_whitelist.phpt
new file mode 100644
index 0000000..8e63a36
--- /dev/null
+++ b/tests/filter/input_filter_request_array_index_whitelist.phpt
@@ -0,0 +1,51 @@
1--TEST--
2suhosin input filter (suhosin.request.array_index_whitelist)
3--INI--
4suhosin.log.syslog=0
5suhosin.log.sapi=0
6suhosin.log.stdout=255
7suhosin.log.script=0
8suhosin.request.array_index_whitelist=abcdefghijklmnopqrstuvwxyz
9--SKIPIF--
10<?php include('skipif.inc'); ?>
11--COOKIE--
12var1[aaa]=1;var2[bbB]=1;var3[ccc][ccC]=1
13--GET--
14var1[aaa]=1&var2[bbB]=1&var3[ccc][ccC]=1
15--POST--
16var1[aaa]=1&var2[bbB]=1&var3[ccc][ccC]=1
17--FILE--
18<?php
19var_dump($_GET);
20var_dump($_POST);
21var_dump($_COOKIE);
22?>
23--EXPECTF--
24array(1) {
25 ["var1"]=>
26 array(1) {
27 ["aaa"]=>
28 string(1) "1"
29 }
30}
31array(1) {
32 ["var1"]=>
33 array(1) {
34 ["aaa"]=>
35 string(1) "1"
36 }
37}
38array(1) {
39 ["var1"]=>
40 array(1) {
41 ["aaa"]=>
42 string(1) "1"
43 }
44}
45ALERT - array index contains not whitelisted characters - dropped variable 'var2[bbB]' (attacker 'REMOTE_ADDR not set', file '%s')
46ALERT - array index contains not whitelisted characters - dropped variable 'var3[ccc][ccC]' (attacker 'REMOTE_ADDR not set', file '%s')
47ALERT - array index contains not whitelisted characters - dropped variable 'var2[bbB]' (attacker 'REMOTE_ADDR not set', file '%s')
48ALERT - array index contains not whitelisted characters - dropped variable 'var3[ccc][ccC]' (attacker 'REMOTE_ADDR not set', file '%s')
49ALERT - array index contains not whitelisted characters - dropped variable 'var2[bbB]' (attacker 'REMOTE_ADDR not set', file '%s')
50ALERT - array index contains not whitelisted characters - dropped variable 'var3[ccc][ccC]' (attacker 'REMOTE_ADDR not set', file '%s')
51ALERT - dropped 6 request variables - (2 in GET, 2 in POST, 2 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s')