[php-maint] [PHP-DEV] CVE-2008-5658 unfixed or new problem with Zip::extractTo in 5.2.x?

sean finney seanius at debian.org
Fri Jan 23 08:06:28 UTC 2009


hi again,

On Fri, Jan 23, 2009 at 08:23:59AM +0100, sean finney wrote:
> it's unfortunate that there isn't a more surgical fix (301 insertions!),
> but i'll take your word for it that it would be too complicated/dangerous
> to try and modify virtual_file_ex() directly.

actually, i think i've found a slightly more graceful workaround :)

since virtual_file_ex is to fragile to be changed, here's a patch that
does the following as a workaround:

- take a temporary copy of the filename
- replace all instances of "^../", "/../", and "/..$" with "///".
- pass this mangled filename to virtual_file_ex for normalization

it seems virtual_file_ex can handle such a filename without problem, and 
with proper formatting the current patch only inserts 22 lines to php_zip.c.
someone should probably double check this code for early-morning coding
errors though :)

what do you think?


	sean
-------------- next part --------------
--- ext/zip/php_zip.c.orig	2009-01-23 08:29:32.000000000 +0100
+++ ext/zip/php_zip.c	2009-01-23 08:56:42.000000000 +0100
@@ -142,6 +142,9 @@
 	char *path_cleaned;
 	size_t path_cleaned_len;
 	cwd_state new_state;
+  char *tmp_file = NULL;
+  char *tmp_needle = NULL;
+  int virtual_ret = 0;
 
 	new_state.cwd = (char*)malloc(1);
 	new_state.cwd[0] = '\0';
@@ -150,7 +153,25 @@
 	/* Clean/normlize the path and then transform any path (absolute or relative)
 		 to a path relative to cwd (../../mydir/foo.txt > mydir/foo.txt)
 	 */
-	virtual_file_ex(&new_state, file, NULL, CWD_EXPAND);
+  tmp_file = strdup(file); 
+  while (tmp_needle=strstr(tmp_file, "/../"))
+  {
+    *(tmp_needle+1)=*(tmp_needle+2)='/';
+  }
+  if (strncmp(tmp_file, "..", 2) == 0 && (file_len == 2 || tmp_file[2] == '/'))
+  {
+    tmp_file[0]=tmp_file[1]='/';
+  }
+  if (file_len > 3 && strncmp(&tmp_file[file_len-2], "..", 2) == 0) 
+  {
+    tmp_file[file_len-1]=tmp_file[file_len-2]='/';
+  }
+	virtual_ret = virtual_file_ex(&new_state, tmp_file, NULL, CWD_EXPAND);
+  free(tmp_file);
+  if (virtual_ret == 1) 
+  {
+    return 0;
+  }
 	path_cleaned =  php_zip_make_relative_path(new_state.cwd, new_state.cwd_length);
 	path_cleaned_len = strlen(path_cleaned);
 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.alioth.debian.org/pipermail/pkg-php-maint/attachments/20090123/af0cdcbd/attachment.pgp 


More information about the pkg-php-maint mailing list