diff options
| author | Ben Fuhrmannek | 2014-07-12 09:25:28 +0200 |
|---|---|---|
| committer | Ben Fuhrmannek | 2014-07-12 09:25:28 +0200 |
| commit | 6bb8cdbbd56c09a6864b40ce21f9a87abd942305 (patch) | |
| tree | ae2455c089646cb118ef1efff3af4b677d3b999e | |
| parent | dd270c094df080ff8438d29e14ec1bbffe0ca993 (diff) | |
introduced suhosin.upload.allow_utf8
| -rw-r--r-- | php_suhosin.h | 1 | ||||
| -rw-r--r-- | suhosin.c | 1 | ||||
| -rw-r--r-- | tests/filter/suhosin_upload_disallow_binary_utf8.phpt | 1 | ||||
| -rw-r--r-- | tests/filter/suhosin_upload_disallow_binary_utf8fail.phpt | 45 | ||||
| -rw-r--r-- | tests/filter/suhosin_upload_remove_binary_utf8.phpt | 1 | ||||
| -rw-r--r-- | tests/filter/suhosin_upload_remove_binary_utf8fail.phpt | 32 | ||||
| -rw-r--r-- | ufilter.c | 18 |
7 files changed, 88 insertions, 11 deletions
diff --git a/php_suhosin.h b/php_suhosin.h index e5604a7..6d2ea80 100644 --- a/php_suhosin.h +++ b/php_suhosin.h | |||
| @@ -150,6 +150,7 @@ ZEND_BEGIN_MODULE_GLOBALS(suhosin) | |||
| 150 | zend_bool upload_disallow_elf; | 150 | zend_bool upload_disallow_elf; |
| 151 | zend_bool upload_disallow_binary; | 151 | zend_bool upload_disallow_binary; |
| 152 | zend_bool upload_remove_binary; | 152 | zend_bool upload_remove_binary; |
| 153 | zend_bool upload_allow_utf8; | ||
| 153 | char *upload_verification_script; | 154 | char *upload_verification_script; |
| 154 | 155 | ||
| 155 | zend_bool no_more_variables; | 156 | zend_bool no_more_variables; |
| @@ -986,6 +986,7 @@ PHP_INI_BEGIN() | |||
| 986 | STD_PHP_INI_ENTRY("suhosin.upload.disallow_elf", "1", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadBool, upload_disallow_elf, zend_suhosin_globals, suhosin_globals) | 986 | STD_PHP_INI_ENTRY("suhosin.upload.disallow_elf", "1", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadBool, upload_disallow_elf, zend_suhosin_globals, suhosin_globals) |
| 987 | STD_PHP_INI_ENTRY("suhosin.upload.disallow_binary", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadBool, upload_disallow_binary, zend_suhosin_globals, suhosin_globals) | 987 | STD_PHP_INI_ENTRY("suhosin.upload.disallow_binary", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadBool, upload_disallow_binary, zend_suhosin_globals, suhosin_globals) |
| 988 | STD_PHP_INI_ENTRY("suhosin.upload.remove_binary", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadBool, upload_remove_binary, zend_suhosin_globals, suhosin_globals) | 988 | STD_PHP_INI_ENTRY("suhosin.upload.remove_binary", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadBool, upload_remove_binary, zend_suhosin_globals, suhosin_globals) |
| 989 | STD_PHP_INI_ENTRY("suhosin.upload.allow_utf8", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadBool, upload_allow_utf8, zend_suhosin_globals, suhosin_globals) | ||
| 989 | STD_PHP_INI_ENTRY("suhosin.upload.verification_script", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadString, upload_verification_script, zend_suhosin_globals, suhosin_globals) | 990 | STD_PHP_INI_ENTRY("suhosin.upload.verification_script", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadString, upload_verification_script, zend_suhosin_globals, suhosin_globals) |
| 990 | 991 | ||
| 991 | 992 | ||
diff --git a/tests/filter/suhosin_upload_disallow_binary_utf8.phpt b/tests/filter/suhosin_upload_disallow_binary_utf8.phpt index 4661dc9..557a8d5 100644 --- a/tests/filter/suhosin_upload_disallow_binary_utf8.phpt +++ b/tests/filter/suhosin_upload_disallow_binary_utf8.phpt | |||
| @@ -7,6 +7,7 @@ suhosin.log.stdout=255 | |||
| 7 | suhosin.log.script=0 | 7 | suhosin.log.script=0 |
| 8 | file_uploads=1 | 8 | file_uploads=1 |
| 9 | suhosin.upload.disallow_binary=On | 9 | suhosin.upload.disallow_binary=On |
| 10 | suhosin.upload.allow_utf8=On | ||
| 10 | max_file_uploads=40 | 11 | max_file_uploads=40 |
| 11 | suhosin.upload.max_uploads=40 | 12 | suhosin.upload.max_uploads=40 |
| 12 | --SKIPIF-- | 13 | --SKIPIF-- |
diff --git a/tests/filter/suhosin_upload_disallow_binary_utf8fail.phpt b/tests/filter/suhosin_upload_disallow_binary_utf8fail.phpt new file mode 100644 index 0000000..413d25a --- /dev/null +++ b/tests/filter/suhosin_upload_disallow_binary_utf8fail.phpt | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | --TEST-- | ||
| 2 | Testing: suhosin.upload.disallow_binary=On with UTF-8 and allow_utf8=Off | ||
| 3 | --INI-- | ||
| 4 | suhosin.log.syslog=0 | ||
| 5 | suhosin.log.sapi=0 | ||
| 6 | suhosin.log.stdout=255 | ||
| 7 | suhosin.log.script=0 | ||
| 8 | file_uploads=1 | ||
| 9 | suhosin.upload.disallow_binary=On | ||
| 10 | suhosin.upload.allow_utf8=Off | ||
| 11 | max_file_uploads=40 | ||
| 12 | suhosin.upload.max_uploads=40 | ||
| 13 | --SKIPIF-- | ||
| 14 | <?php include('skipif.inc'); ?> | ||
| 15 | --COOKIE-- | ||
| 16 | --GET-- | ||
| 17 | --POST_RAW-- | ||
| 18 | Content-Type: multipart/form-data; boundary=bound | ||
| 19 | --bound | ||
| 20 | Content-Disposition: form-data; name="test"; filename="test" | ||
| 21 | |||
| 22 | Spaß am Gerät! | ||
| 23 | |||
| 24 | --bound-- | ||
| 25 | --FILE-- | ||
| 26 | <?php | ||
| 27 | var_dump($_FILES); | ||
| 28 | ?> | ||
| 29 | --EXPECTF-- | ||
| 30 | array(1) { | ||
| 31 | ["test"]=> | ||
| 32 | array(5) { | ||
| 33 | ["name"]=> | ||
| 34 | string(4) "test" | ||
| 35 | ["type"]=> | ||
| 36 | string(0) "" | ||
| 37 | ["tmp_name"]=> | ||
| 38 | string(0) "" | ||
| 39 | ["error"]=> | ||
| 40 | int(8) | ||
| 41 | ["size"]=> | ||
| 42 | int(0) | ||
| 43 | } | ||
| 44 | } | ||
| 45 | ALERT - uploaded file contains binary data - file dropped (attacker 'REMOTE_ADDR not set', file '%s') | ||
diff --git a/tests/filter/suhosin_upload_remove_binary_utf8.phpt b/tests/filter/suhosin_upload_remove_binary_utf8.phpt index 2d10eaa..6fbd240 100644 --- a/tests/filter/suhosin_upload_remove_binary_utf8.phpt +++ b/tests/filter/suhosin_upload_remove_binary_utf8.phpt | |||
| @@ -8,6 +8,7 @@ suhosin.log.script=0 | |||
| 8 | file_uploads=1 | 8 | file_uploads=1 |
| 9 | suhosin.upload.disallow_binary=Off | 9 | suhosin.upload.disallow_binary=Off |
| 10 | suhosin.upload.remove_binary=On | 10 | suhosin.upload.remove_binary=On |
| 11 | suhosin.upload.allow_utf8=On | ||
| 11 | max_file_uploads=40 | 12 | max_file_uploads=40 |
| 12 | suhosin.upload.max_uploads=40 | 13 | suhosin.upload.max_uploads=40 |
| 13 | --SKIPIF-- | 14 | --SKIPIF-- |
diff --git a/tests/filter/suhosin_upload_remove_binary_utf8fail.phpt b/tests/filter/suhosin_upload_remove_binary_utf8fail.phpt new file mode 100644 index 0000000..5c31115 --- /dev/null +++ b/tests/filter/suhosin_upload_remove_binary_utf8fail.phpt | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | --TEST-- | ||
| 2 | Testing: suhosin.upload.remove_binary=On with UTF-8 and allow_utf8=Off | ||
| 3 | --INI-- | ||
| 4 | suhosin.log.syslog=0 | ||
| 5 | suhosin.log.sapi=0 | ||
| 6 | suhosin.log.stdout=255 | ||
| 7 | suhosin.log.script=0 | ||
| 8 | file_uploads=1 | ||
| 9 | suhosin.upload.disallow_binary=Off | ||
| 10 | suhosin.upload.remove_binary=On | ||
| 11 | suhosin.upload.allow_utf8=Off | ||
| 12 | max_file_uploads=40 | ||
| 13 | suhosin.upload.max_uploads=40 | ||
| 14 | --SKIPIF-- | ||
| 15 | <?php include('skipif.inc'); ?> | ||
| 16 | --COOKIE-- | ||
| 17 | --GET-- | ||
| 18 | --POST_RAW-- | ||
| 19 | Content-Type: multipart/form-data; boundary=bound | ||
| 20 | --bound | ||
| 21 | Content-Disposition: form-data; name="test"; filename="test" | ||
| 22 | |||
| 23 | Spaß am Gerät! | ||
| 24 | |||
| 25 | --bound-- | ||
| 26 | --FILE-- | ||
| 27 | <?php | ||
| 28 | var_dump(file_get_contents($_FILES['test']['tmp_name'])); | ||
| 29 | ?> | ||
| 30 | --EXPECTF-- | ||
| 31 | string(13) "Spa am Gert! | ||
| 32 | " \ No newline at end of file | ||
| @@ -281,10 +281,10 @@ int suhosin_rfc1867_filter(unsigned int event, void *event_data, void **extra TS | |||
| 281 | int n; | 281 | int n; |
| 282 | cpend = mefd->data + mefd->length; | 282 | cpend = mefd->data + mefd->length; |
| 283 | for (char *cp = mefd->data; cp < cpend; cp++) { | 283 | for (char *cp = mefd->data; cp < cpend; cp++) { |
| 284 | if (*cp >= 32) { | 284 | if (*cp >= 32 || isspace(*cp)) { |
| 285 | continue; | 285 | continue; |
| 286 | } | 286 | } |
| 287 | if (*cp & 0x80) { | 287 | if ((*cp & 0x80) && SUHOSIN_G(upload_allow_utf8)) { |
| 288 | SDEBUG("checking char %x", *cp); | 288 | SDEBUG("checking char %x", *cp); |
| 289 | if ((n = suhosin_validate_utf8_multibyte(cp))) { // valid UTF8 multibyte character | 289 | if ((n = suhosin_validate_utf8_multibyte(cp))) { // valid UTF8 multibyte character |
| 290 | cp += n - 1; | 290 | cp += n - 1; |
| @@ -292,16 +292,12 @@ int suhosin_rfc1867_filter(unsigned int event, void *event_data, void **extra TS | |||
| 292 | } | 292 | } |
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | if (!isspace(*cp)) { | 295 | suhosin_log(S_FILES, "uploaded file contains binary data - file dropped"); |
| 296 | suhosin_log(S_FILES, "uploaded file contains binary data - file dropped"); | 296 | if (!SUHOSIN_G(simulation)) { |
| 297 | if (!SUHOSIN_G(simulation)) { | 297 | goto continue_with_failure; |
| 298 | goto continue_with_failure; | ||
| 299 | } | ||
| 300 | break; | ||
| 301 | } | 298 | } |
| 302 | 299 | break; | |
| 303 | } | 300 | } |
| 304 | |||
| 305 | } | 301 | } |
| 306 | 302 | ||
| 307 | if (SUHOSIN_G(upload_remove_binary)) { | 303 | if (SUHOSIN_G(upload_remove_binary)) { |
| @@ -313,7 +309,7 @@ int suhosin_rfc1867_filter(unsigned int event, void *event_data, void **extra TS | |||
| 313 | for (i=0, j=0; i<mefd->length; i++) { | 309 | for (i=0, j=0; i<mefd->length; i++) { |
| 314 | if (mefd->data[i] >= 32 || isspace(mefd->data[i])) { | 310 | if (mefd->data[i] >= 32 || isspace(mefd->data[i])) { |
| 315 | mefd->data[j++] = mefd->data[i]; | 311 | mefd->data[j++] = mefd->data[i]; |
| 316 | } else if (mefd->data[i] & 0x80) { | 312 | } else if (SUHOSIN_G(upload_allow_utf8) && mefd->data[i] & 0x80) { |
| 317 | n = suhosin_validate_utf8_multibyte(mefd->data + i); | 313 | n = suhosin_validate_utf8_multibyte(mefd->data + i); |
| 318 | if (!n) { continue; } | 314 | if (!n) { continue; } |
| 319 | while (n) { | 315 | while (n) { |
