CVE-2012-0807 (published 2012-01-27T00:55Z)

Stack-based buffer overflow in the suhosin_encrypt_single_cookie function in the transparent cookie-encryption feature in the Suhosin extension before 0.9.33 for PHP, when suhosin.cookie.encrypt and suhosin.multiheader are enabled, might allow remote attackers to execute arbitrary code via a long string that is used in a Set-Cookie HTTP header.

Severity: MEDIUM
CVSS v2 base score: 5.1 (AV:N/AC:H/Au:N/C:P/I:P/A:P)

Weakness information:
cwe_id: CWE-119
cwe_name: Improper Restriction of Operations within the Bounds of a Memory Buffer
description: The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data.
extended_description: 
            Certain languages allow direct addressing of memory locations and do not automatically ensure that these locations are valid for the memory buffer that is being referenced. This can cause read or write operations to be performed on memory locations that may be associated with other variables, data structures, or internal program data.
         
         

Fix information:
repo_url: https://github.com/stefanesser/suhosin
commit_details: repo_url: https://github.com/stefanesser/suhosin
author: Stefan Esser
author_date: 2012-01-14 09:44:17+01:00
msg: Fixed stack based buffer overflow in transparent cookie encryption (see separate advisory)
repository: repo_url: https://github.com/stefanesser/suhosin
repo_name: sektioneins/suhosin
description: SUHOSIN [수호신] for PHP 5.x - The PHP security extension.
repo_language: C
owner: stefanesser
file_changes: filename: Changelog
change_type: ModificationType.MODIFY
diff: @@ -1,5 +1,6 @@
 2012-01-11 - 0.9.33-dev
 
+    - Fixed stack based buffer overflow in transparent cookie encryption (see separate advisory)
     - Fixed that disabling HTTP response splitting protection also disabled NUL byte protection in HTTP headers
     - Removed crypt() support - because not used for PHP >= 5.3.0 anyway
 

programming_language: Markdown
filename: header.c
change_type: ModificationType.MODIFY
diff: @@ -40,28 +40,20 @@ static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_
 
 char *suhosin_encrypt_single_cookie(char *name, int name_len, char *value, int value_len, char *key TSRMLS_DC)
 {
-	char buffer[4096];
-    char buffer2[4096];
-	char *buf = buffer, *buf2 = buffer2, *d, *d_url;
-    int l;
-
-	if (name_len > sizeof(buffer)-2) {
-		buf = estrndup(name, name_len);
-	} else {
-		memcpy(buf, name, name_len);
-		buf[name_len] = 0;
-	}
+	char *buf, *buf2, *d, *d_url;
+	int l;
+
+	buf = estrndup(name, name_len);
+	
 	
 	name_len = php_url_decode(buf, name_len);
-    normalize_varname(buf);
-    name_len = strlen(buf);
+	normalize_varname(buf);
+	name_len = strlen(buf);
 	
 	if (SUHOSIN_G(cookie_plainlist)) {
 		if (zend_hash_exists(SUHOSIN_G(cookie_plainlist), buf, name_len+1)) {
 encrypt_return_plain:
-			if (buf != buffer) {
-				efree(buf);
-			}
+			efree(buf);
 			return estrndup(value, value_len);
 		}
 	} else if (SUHOSIN_G(cookie_cryptlist)) {
@@ -70,52 +62,34 @@ encrypt_return_plain:
 		}
 	}
 	
-	if (strlen(value) <= sizeof(buffer2)-2) {
-		memcpy(buf2, value, value_len);
-		buf2[value_len] = 0;
-	} else {
-		buf2 = estrndup(value, value_len);
-	}
+	buf2 = estrndup(value, value_len);
 	
 	value_len = php_url_decode(buf2, value_len);
 	
 	d = suhosin_encrypt_string(buf2, value_len, buf, name_len, key TSRMLS_CC);
 	d_url = php_url_encode(d, strlen(d), &l);
 	efree(d);
-    if (buf != buffer) {
-		efree(buf);
-	}
-    if (buf2 != buffer2) {
-		efree(buf2);
-	}
+	efree(buf);
+	efree(buf2);
 	return d_url;
 }
 
 char *suhosin_decrypt_single_cookie(char *name, int name_len, char *value, int value_len, char *key, char **where TSRMLS_DC)
 {
-	char buffer[4096];
-    char buffer2[4096];
     int o_name_len = name_len;
-	char *buf = buffer, *buf2 = buffer2, *d, *d_url;
+	char *buf, *buf2, *d, *d_url;
 	int l;
 
-	if (name_len > sizeof(buffer)-2) {
-		buf = estrndup(name, name_len);
-	} else {
-		memcpy(buf, name, name_len);
-		buf[name_len] = 0;
-	}
-	
+	buf = estrndup(name, name_len);
+		
 	name_len = php_url_decode(buf, name_len);
-    normalize_varname(buf);
-    name_len = strlen(buf);
+	normalize_varname(buf);
+	name_len = strlen(buf);
 	
 	if (SUHOSIN_G(cookie_plainlist)) {
 		if (zend_hash_exists(SUHOSIN_G(cookie_plainlist), buf, name_len+1)) {
 decrypt_return_plain:
-			if (buf != buffer) {
-				efree(buf);
-			}
+			efree(buf);
             memcpy(*where, name, o_name_len);
             *where += o_name_len;
             **where = '='; *where +=1;
@@ -130,12 +104,7 @@ decrypt_return_plain:
 	}
 	
 	
-	if (strlen(value) <= sizeof(buffer2)-2) {
-		memcpy(buf2, value, value_len);
-		buf2[value_len] = 0;
-	} else {
-		buf2 = estrndup(value, value_len);
-	}
+	buf2 = estrndup(value, value_len);
 	
 	value_len = php_url_decode(buf2, value_len);
 	
@@ -152,12 +121,8 @@ decrypt_return_plain:
 	*where += l;
 	efree(d_url);
 skip_cookie:
-	if (buf != buffer) {
-		efree(buf);
-	}
-	if (buf2 != buffer2) {
-		efree(buf2);
-	}
+	efree(buf);
+	efree(buf2);
 	return *where;
 }
 

programming_language: C