diff options
| author | Stefan Esser | 2015-05-20 11:59:13 +0200 |
|---|---|---|
| committer | Stefan Esser | 2015-05-20 11:59:13 +0200 |
| commit | 7670e669c000f835169dd9b85af6d2f45f303040 (patch) | |
| tree | 162608d1dd8e3c653d1cd6ac8b619515ba4fa5b5 | |
| parent | 2bde2784897fed6dbe238af53ede0a0421239d35 (diff) | |
Fix high CPU consumption DOS through many newlines in RFC1867 MIME headers
| -rw-r--r-- | Changelog | 2 | ||||
| -rw-r--r-- | php_suhosin.h | 1 | ||||
| -rw-r--r-- | rfc1867_new.c | 8 | ||||
| -rw-r--r-- | suhosin.c | 1 | ||||
| -rw-r--r-- | suhosin.ini | 10 |
5 files changed, 22 insertions, 0 deletions
| @@ -2,6 +2,8 @@ | |||
| 2 | - removed code compatibility for PHP <5.4 (lots of code + ifdefs) | 2 | - removed code compatibility for PHP <5.4 (lots of code + ifdefs) |
| 3 | - allow https location for suhosin.filter.action | 3 | - allow https location for suhosin.filter.action |
| 4 | - fixed newline detection for suhosin.mail.protect | 4 | - fixed newline detection for suhosin.mail.protect |
| 5 | - Added suhosin.upload.max_newlines to protect againt DOS attack via many | ||
| 6 | MIME headers in RFC1867 uploads | ||
| 5 | 7 | ||
| 6 | 2014-12-12 - 0.9.37.1 | 8 | 2014-12-12 - 0.9.37.1 |
| 7 | - Changed version string to 0.9.37.1 (without -dev) | 9 | - Changed version string to 0.9.37.1 (without -dev) |
diff --git a/php_suhosin.h b/php_suhosin.h index 7b86e7a..fd61a0a 100644 --- a/php_suhosin.h +++ b/php_suhosin.h | |||
| @@ -203,6 +203,7 @@ ZEND_BEGIN_MODULE_GLOBALS(suhosin) | |||
| 203 | 203 | ||
| 204 | /* fileupload */ | 204 | /* fileupload */ |
| 205 | long upload_limit; | 205 | long upload_limit; |
| 206 | long upload_max_newlines; | ||
| 206 | long num_uploads; | 207 | long num_uploads; |
| 207 | zend_bool upload_disallow_elf; | 208 | zend_bool upload_disallow_elf; |
| 208 | zend_bool upload_disallow_binary; | 209 | zend_bool upload_disallow_binary; |
diff --git a/rfc1867_new.c b/rfc1867_new.c index 2a8b3ab..dfdc1d9 100644 --- a/rfc1867_new.c +++ b/rfc1867_new.c | |||
| @@ -387,6 +387,7 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header T | |||
| 387 | char *line; | 387 | char *line; |
| 388 | mime_header_entry prev_entry = {0}, entry; | 388 | mime_header_entry prev_entry = {0}, entry; |
| 389 | int prev_len, cur_len; | 389 | int prev_len, cur_len; |
| 390 | int newlines = 0; | ||
| 390 | 391 | ||
| 391 | /* didn't find boundary, abort */ | 392 | /* didn't find boundary, abort */ |
| 392 | if (!find_boundary(self, self->boundary TSRMLS_CC)) { | 393 | if (!find_boundary(self, self->boundary TSRMLS_CC)) { |
| @@ -416,6 +417,7 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header T | |||
| 416 | 417 | ||
| 417 | entry.value = estrdup(value); | 418 | entry.value = estrdup(value); |
| 418 | entry.key = estrdup(key); | 419 | entry.key = estrdup(key); |
| 420 | newlines = 0; | ||
| 419 | 421 | ||
| 420 | } else if (zend_llist_count(header)) { /* If no ':' on the line, add to previous line */ | 422 | } else if (zend_llist_count(header)) { /* If no ':' on the line, add to previous line */ |
| 421 | 423 | ||
| @@ -428,6 +430,12 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header T | |||
| 428 | entry.value[cur_len + prev_len] = '\0'; | 430 | entry.value[cur_len + prev_len] = '\0'; |
| 429 | 431 | ||
| 430 | entry.key = estrdup(prev_entry.key); | 432 | entry.key = estrdup(prev_entry.key); |
| 433 | newlines++; | ||
| 434 | if (newlines > SUHOSIN_G(upload_max_newlines)) { | ||
| 435 | SUHOSIN_G(abort_request) = 1; | ||
| 436 | suhosin_log(S_FILES, "configured maximum number of newlines in RFC1867 MIME headers limit exceeded - dropping rest of upload"); | ||
| 437 | return 0; | ||
| 438 | } | ||
| 431 | 439 | ||
| 432 | zend_llist_remove_tail(header); | 440 | zend_llist_remove_tail(header); |
| 433 | } else { | 441 | } else { |
| @@ -856,6 +856,7 @@ PHP_INI_BEGIN() | |||
| 856 | STD_PHP_INI_ENTRY("suhosin.post.disallow_ws", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdatePostBool, disallow_post_ws, zend_suhosin_globals, suhosin_globals) | 856 | STD_PHP_INI_ENTRY("suhosin.post.disallow_ws", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdatePostBool, disallow_post_ws, zend_suhosin_globals, suhosin_globals) |
| 857 | 857 | ||
| 858 | STD_PHP_INI_ENTRY("suhosin.upload.max_uploads", "25", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadLong, upload_limit, zend_suhosin_globals, suhosin_globals) | 858 | STD_PHP_INI_ENTRY("suhosin.upload.max_uploads", "25", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadLong, upload_limit, zend_suhosin_globals, suhosin_globals) |
| 859 | STD_PHP_INI_ENTRY("suhosin.upload.max_newlines", "100", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadLong, upload_max_newlines, zend_suhosin_globals, suhosin_globals) | ||
| 859 | STD_PHP_INI_ENTRY("suhosin.upload.disallow_elf", "1", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadBool, upload_disallow_elf, zend_suhosin_globals, suhosin_globals) | 860 | STD_PHP_INI_ENTRY("suhosin.upload.disallow_elf", "1", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadBool, upload_disallow_elf, zend_suhosin_globals, suhosin_globals) |
| 860 | STD_PHP_INI_ENTRY("suhosin.upload.disallow_binary", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadBool, upload_disallow_binary, zend_suhosin_globals, suhosin_globals) | 861 | STD_PHP_INI_ENTRY("suhosin.upload.disallow_binary", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadBool, upload_disallow_binary, zend_suhosin_globals, suhosin_globals) |
| 861 | STD_PHP_INI_ENTRY("suhosin.upload.remove_binary", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadBool, upload_remove_binary, zend_suhosin_globals, suhosin_globals) | 862 | STD_PHP_INI_ENTRY("suhosin.upload.remove_binary", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadBool, upload_remove_binary, zend_suhosin_globals, suhosin_globals) |
diff --git a/suhosin.ini b/suhosin.ini index b37013b..4dfbf43 100644 --- a/suhosin.ini +++ b/suhosin.ini | |||
| @@ -1334,6 +1334,16 @@ | |||
| 1334 | ;suhosin.upload.max_uploads = 25 | 1334 | ;suhosin.upload.max_uploads = 25 |
| 1335 | ; | 1335 | ; |
| 1336 | 1336 | ||
| 1337 | ; suhosin.upload.max_newlines | ||
| 1338 | ; -------------------------- | ||
| 1339 | ; * Type: Integer | ||
| 1340 | ; * Default: 100 | ||
| 1341 | ; | ||
| 1342 | ; Defines the maximum number of newlines in rfc1867 mime headers. | ||
| 1343 | ; | ||
| 1344 | ;suhosin.upload.max_newlines = 100 | ||
| 1345 | ; | ||
| 1346 | |||
| 1337 | ; suhosin.upload.disallow_elf | 1347 | ; suhosin.upload.disallow_elf |
| 1338 | ; --------------------------- | 1348 | ; --------------------------- |
| 1339 | ; * Type: Boolean | 1349 | ; * Type: Boolean |
