Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Wed, 03 Apr 2013 09:45:59 -0600
From: Kurt Seifried <kseifried@...hat.com>
To: oss-security@...ts.openwall.com
CC: Henri Salo <henri@...v.fi>
Subject: Re: CVE request: WordPress plugin user-photo file
 upload arbitrary PHP code execution

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 03/26/2013 01:29 PM, Henri Salo wrote:
> Hello Kurt and list members,
> 
> Can I get CVE identifier for WordPress plugin user-photo file
> upload arbitrary PHP code execution security vulnerability.
> Different issue than CVE-2012-2920.
> 
> References: http://osvdb.org/71071 
> http://seclists.org/fulldisclosure/2011/Feb/354
> 
> Affected: 0.9.4 (older probably affected too) OSVDB currently lists
> fixed version as 0.9.5.1, but fixed in version is 0.9.5 Discovery
> date: 2010-07-01 Vendor informed date: 2011-01-27 Time to exploit:
> 231 days
> 
> Someone had fun for a long time. Should get CVE-2011-XXXX, yes?
> 
> By looking at the patch for example lines below can be bypassed
> using null character in the filename:
> 
> +      else if( !preg_match("/\.(" . join('|',
> $userphoto_validextensions) . ")$/i",
> $_FILES['userphoto_image_file']['name']) ){ +        $error =
> sprintf(__("The file extension &ldquo;%s&rdquo; is not allowed.
> Must be one of: %s.", 'user-photo'), preg_replace('/.*\./', '',
> $_FILES['userphoto_image_file']['name']), join(', ',
> $userphoto_validextensions)); +      }
> 
> Line below renames the file to e.g. 1.jpg so it should not be
> executable in well configured www-server:
> 
> +          $imagefile = "$userID." .
> preg_replace('{^.+?\.(?=\w+$)}', '',
> strtolower($_FILES['userphoto_image_file']['name']));
> 
> Whole diff below:
> 
> """ Plugin Name: User Photo Plugin URI:
> http://wordpress.org/extend/plugins/user-photo/ Description: Allows
> users to associate photos with their accounts by accessing their
> "Your Profile" page. Uploaded images are resized to fit the
> dimensions specified on the options page; a thumbnail image is also
> generated. New template tags introduced are:
> <code>userphoto_the_author_photo</code>,
> <code>userphoto_the_author_thumbnail</code>,
> <code>userphoto_comment_author_photo</code>, and
> <code>userphoto_comment_author_thumbnail</code>. Uploaded images
> may be moderated by administrators. -Version: 0.9.4 -Author: <a
> href="http://weston.ruter.net/">Weston Ruter</a>, <a
> href="http://dev.dave-wagner.com/">Dave Wagner's Dev Site</a> 
> +Version: 0.9.5 +Author: <a href="http://weston.ruter.net/">Weston
> Ruter</a>
> 
> Original code by Weston Ruter <http://weston.ruter.net> at Shepherd
> Interactive <http://shepherd-interactive.com>. -Continued
> development and maintenance by Dave Wagner
> <http://dev.dave-wagner.com/> +Continued development and
> maintenance by Dave Wagner (cptnwinky)
> <http://dev.dave-wagner.com/>
> 
> GNU General Public License, Free Software Foundation
> <http://creativecommons.org/licenses/GPL/2.0/> This program is free
> software; you can redistribute it and/or modify @@ -47,6 +47,7 @@ 
> "image/png" => true, "image/x-png" => true ); 
> +$userphoto_validextensions = array('jpeg', 'jpg', 'gif', 'png');
> 
> define('USERPHOTO_PENDING', 0); define('USERPHOTO_REJECTED', 1); @@
> -316,6 +317,7 @@ function userphoto_thumbnail($user, $before = '',
> $after = '', $attributes = arr
> 
> function userphoto_profile_update($userID){ global
> $userphoto_validtypes; +  global $userphoto_validextensions; global
> $current_user;
> 
> $userdata = get_userdata($userID); @@ -376,10 +378,15 @@ function
> userphoto_profile_update($userID){ $error = __("File upload failed
> due to unknown error.", 'user-photo'); } } -      else
> if(!$_FILES['userphoto_image_file']['size']) +      else if(
> !$_FILES['userphoto_image_file']['size'] ){ $error =
> sprintf(__("The file &ldquo;%s&rdquo; was not uploaded. Did you
> provide the correct filename?", 'user-photo'),
> $_FILES['userphoto_image_file']['name']); -      else
> if(@!$userphoto_validtypes[$_FILES['userphoto_image_file']['type']])
> //!preg_match("/\.(" . join('|', $userphoto_validextensions) .
> ")$/i", $_FILES['userphoto_image_file']['name'])) || +      } +
> else if( !preg_match("/\.(" . join('|', $userphoto_validextensions)
> . ")$/i", $_FILES['userphoto_image_file']['name']) ){ +
> $error = sprintf(__("The file extension &ldquo;%s&rdquo; is not
> allowed. Must be one of: %s.", 'user-photo'),
> preg_replace('/.*\./', '',
> $_FILES['userphoto_image_file']['name']), join(', ',
> $userphoto_validextensions)); +      } +      else if(
> @!$userphoto_validtypes[$_FILES['userphoto_image_file']['type']]
> ){ $error = sprintf(__("The uploaded file type &ldquo;%s&rdquo; is
> not allowed.", 'user-photo'),
> $_FILES['userphoto_image_file']['type']); +      }
> 
> $tmppath = $_FILES['userphoto_image_file']['tmp_name'];
> 
> @@ -414,8 +421,10 @@ function userphoto_profile_update($userID){ 
> #umask($umask);
> 
> if(!$error){ -          #$oldFile =
> basename($userdata->userphoto_image_file); -          $imagefile =
> preg_replace('/^.+(?=\.\w+$)/', $userdata->user_nicename,
> strtolower($_FILES['userphoto_image_file']['name'])); +
> $oldimagefile = basename($userdata->userphoto_image_file); +
> $oldthumbfile = basename($userdata->userphoto_thumb_file); +
> #$imagefile = preg_replace('/^.+(?=\.\w+$)/',
> $userdata->user_nicename,
> strtolower($_FILES['userphoto_image_file']['name'])); +
> $imagefile = "$userID." . preg_replace('{^.+?\.(?=\w+$)}', '',
> strtolower($_FILES['userphoto_image_file']['name'])); $imagepath =
> $dir . '/' . $imagefile; $thumbfile = preg_replace("/(?=\.\w+$)/",
> '.thumbnail', $imagefile); $thumbpath = $dir . '/' . $thumbfile; @@
> -448,7 +457,7 @@ function userphoto_profile_update($userID){ $admin
> = get_userdata($admin_notified); @wp_mail($admin->user_email, "User
> Photo for " . $userdata->display_name . " Needs Approval", -
> get_option("home") . "/wp-admin/user-edit.php?user_id=" .
> $userdata->ID . "#userphoto"); +
> get_option("siteurl") . "/wp-admin/user-edit.php?user_id=" .
> $userdata->ID . "#userphoto"); } } else { @@ -460,9 +469,12 @@
> function userphoto_profile_update($userID){ 
> update_usermeta($userID, "userphoto_thumb_file", $thumbfile); 
> update_usermeta($userID, "userphoto_thumb_width", $thumbinfo[0]); 
> update_usermeta($userID, "userphoto_thumb_height", $thumbinfo[1]); 
> - -            #if($oldFile && $oldFile != $newFile) -            #
> @unlink($dir . '/' . $oldFile); + +            //Delete old
> thumbnail if it has a different filename (extension) +
> if($oldimagefile != $imagefile) +              @unlink($dir . '/' .
> $oldimagefile); +            if($oldthumbfile != $thumbfile) +
> @unlink($dir . '/' . $oldthumbfile); } } } """
> 
> -- Henri Salo


Please use CVE-2013-1916 for this issue.


- -- 
Kurt Seifried Red Hat Security Response Team (SRT)
PGP: 0x5E267993 A90B F995 7350 148F 66BF 7554 160D 4553 5E26 7993
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.13 (GNU/Linux)

iQIcBAEBAgAGBQJRXE63AAoJEBYNRVNeJnmT8qgP/22mDvF4/xoOnV3X6S+sBIsP
mxQ3vA7ve+rH0rL8t/J4/9732BWgP5JpQZAhb6UKDM99nrWuPo+Lziuqy7XY26RR
O4NRhoxZGLL9Vs2WIjTjNufiIu8esjqqM2iSME3Ax+PJcqvnKEQMrFPGrih4gRou
kBhB/n8IZJ/dHull5RDx74xp3VV1VyZvSZKHx/Fv+JNoPjTWywaFZ2Kht79YLXYH
4hXPtr96d4eBE7tZD3Wxx6l1dOMDvO7gPHG7ItstLhT0EW+2LKryGycu6Qi+yiXG
zrQbv6/1Fi+mfxkteStHANhu/1Ae3wLhPVaQAmB5ecPH5dJHCFWR6f/KjRGf77SG
TSjV74QluneIpeJbAsyP8zzrSL5394/BgL7zSXqwzoqIGFO+7WQzjJu33gjnAiaM
46xBwwerxDESdpCd3iP3UGsL8UUS7d9OhVNdKhmMXiI7Di4S68hTMq/QPIF1no/O
L3fWIkdonohZ27I34fMDf+6ve8q+l5oFv//+1TkBSmS8J2o+WaCp2i9jFksAeT1m
xqgen9aUB2IhK7kBntJqqvjzcu+iuaciOpjnb4hchb975WPuL7D9hINrzkAmfcwN
YCz6cN4yA3+nVnUAVbpWVtKLp6UDyGCRtNx4x3cPTYRytsfOGnZu78fUstPSw9Ch
5r0ouO9WLQXyuCC4bWRQ
=UuLk
-----END PGP SIGNATURE-----

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.