summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Esser2015-05-20 11:59:13 +0200
committerStefan Esser2015-05-20 11:59:13 +0200
commit7670e669c000f835169dd9b85af6d2f45f303040 (patch)
tree162608d1dd8e3c653d1cd6ac8b619515ba4fa5b5
parent2bde2784897fed6dbe238af53ede0a0421239d35 (diff)
Fix high CPU consumption DOS through many newlines in RFC1867 MIME headers
-rw-r--r--Changelog2
-rw-r--r--php_suhosin.h1
-rw-r--r--rfc1867_new.c8
-rw-r--r--suhosin.c1
-rw-r--r--suhosin.ini10
5 files changed, 22 insertions, 0 deletions
diff --git a/Changelog b/Changelog
index a6b7e3a..53dba31 100644
--- a/Changelog
+++ b/Changelog
@@ -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
62014-12-12 - 0.9.37.1 82014-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 {
diff --git a/suhosin.c b/suhosin.c
index f91bb30..9e2d017 100644
--- a/suhosin.c
+++ b/suhosin.c
@@ -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