| DetailsAffected Software:WordPress Core Fixed in Version:2.8 Issue Type:Cross Site Scripting Original Code:Found Here DetailsThis week’s bug was subtle. The patch submitted by the developer addresses an XSS bug. Looking at the diff,we see that $title and $selection come from the query string. These values are fixed up before being assigned to a variable. The developers changed the way $title is assigned in the diff. It’s difficult to see why $title needs to be changed,so we’ll ignore that change for now. $selection gives some hints towards XSS. $selection is assigned from the query string value $_GET[‘s’] which is sent through the trim() and aposfix() functions. Immediately following the $selection variable assignment we see the $selection being manipulated with some HTML tags. This is a good indication that $selection will eventually be used to build HTML markup. I usually recommend developers encode/sanitize values as close to the point of consumption as possible,but this case is different. $selection contains HTML tags (the <p>and </p>tags),so encoding the whole value at the point of consumption will also encode those tags. The <p>tags are probably designed to be rendered by the browser. Due to the mixing of HTML tags and regular data,the developer will have to encode the user controlled values during variable assignment. This is exactly what the WordPress developers did in the patch. Developers Solution<?phprequire_once('admin.php');header('Content-Type:' . get_option('html_type') . ';charset=' . get_option('blog_charset'));if ( ! current_user_can('edit_posts') )wp_die( __( 'Cheatin’uh?' ) );function aposfix($text){$translation_table[chr(34)] = '"';$translation_table[chr(38)] = '&';$translation_table[chr(39)] = ''';return preg_replace("/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,3};)/","&",strtr($text,$translation_table))}function press_it(){// define some basic variables$quick['post_status'] = 'draft';// set as draft first$quick['post_category'] = isset($_REQUEST['post_category']) ? $_REQUEST['post_category']:null;$quick['tax_input'] = isset($_REQUEST['tax_input']) ? $_REQUEST['tax_input']:'';$quick['post_title'] = isset($_REQUEST['title']) ? $_REQUEST['title']:'';$quick['post_content'] = '';// insert the post with nothing in it,to get an ID$post_ID = wp_insert_post($quick,true);$content = isset($_REQUEST['content']) ? $_REQUEST['content']:'';$upload = false;if( !empty($_REQUEST['photo_src']) &¤t_user_can('upload_files') )foreach( (array) $_REQUEST['photo_src'] as $key =>$image)// see if files exist in content - we don't want to upload non-used selected files.if( strpos($_REQUEST['content'],$image) !== false ){$desc = isset($_REQUEST['photo_description'][$key]) ? $_REQUEST['photo_description'][$key]:'';$upload = media_sideload_image($image,$post_ID,$desc);// Replace the POSTED content <img>with correct uploaded ones. Regex contains fix for Magic Quotesif( !is_wp_error($upload) ) $content = preg_replace('/<img ([^>]*)src=\\\?(\"|\')'.preg_quote($image,'/').'\\\?(\2)([^>\/]*)\function blogger_getUsersBlogs($args){$this->escape($args);$user_login = $args[1];$user_pass = $args[2];if (!$this->login_pass_ok($user_login,$user_pass)){return $this->error}set_current_user(0,$user_login);$is_admin = current_user_can('level_8');$struct = array('isAdmin' =>$is_admin,'url' =>get_option('home') . '/','blogid' =>'1','blogName' =>get_option('blogname'));return array($struct)}...snip...?>DetailsAffected Software:AskApache Password Protector Fixed in Version:4.0.1 Issue Type:Cross Site Scripting (XSS) Original Code:Found Here DescriptionUpon first glance,we see that the vulnerable code sample comes from an error page of some sort. Error pages are often overlooked when it comes to security (or even general QA). Make sure you put your error pages through the same rigorous security process as you would any other page. The Same Origin Policy won’t distinguish between a forgotten error page and the highly trafficked portal page of your web application. A vulnerability on an error page can have the same devastating effect as a vulnerability on the main portal page. Looking at this bug,we see that the error page is a bit too helpful and echoes back all the information contained in the $_SERVER superglobal. Unfortunately,this superglobal contains all sorts of user/attacker controlled information,resulting in XSS. In this fix,the developers wisely removed the vulnerable line entirely. Developers Solution<?phpob_start();//http://www.askapache.com/htaccess/apache-status-code-headers-errordocument.html... <SNIP>...if (isset($_SERVER['REDIRECT_STATUS'])) $err_code = $_SERVER['REDIRECT_STATUS'];$err_req_meth = $_SERVER['REQUEST_METHOD'];$err_req = htmlentities(strip_tags($_SERVER['REQUEST_URI']));$err_phrase = $err_status_codes[$err_code][0];$err_body = str_replace( array('INTERROR','THEREQUESTURI','THEREQMETH'),array('The server encountered an internal error or misconfiguration and was unable to complete your request.',$err_req,$err_req_meth),$err_status_codes[$err_code][1]);@header("HTTP/1.1 $err_code $err_phrase",1);@header("Status:$err_code $err_phrase",1);//400 || 408 || 413 || 414 || 500 || 503 || 501//@header("Connection:close",1);if ( $err_code=='400'||$err_code=='403'||$err_code=='405'||$err_code[0]=='5'){@header("Connection:close",1);if ($err_code == '405') @header('Allow:GET,HEAD,POST,OPTIONS,TRACE');echo "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html>\n<head>\n<title>{$err_code}{$err_phrase}</title>\n<h1>{$err_phrase}</h1>\n<p>{$err_body}<br>\n</p>\n</body></html>"} else echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xml:lang="en"lang="en"><head><title>'.$err_code.' '.$err_phrase.'</title><meta http-equiv="content-type"content="text/html;charset=UTF-8"/></head><body><h1>'.$err_code.' '.$err_phrase.'</h1><hr /><p>'.$err_body.'<br /></p><pre>-'.print_r($_SERVER,1).'</pre></body></html>';?>DetailsAffected Software:WP-Slimbox 2 Fixed in Version:1.0.1 Issue Type:Cross Site Scripting (XSS) Original Code:Found Here DescriptionA bit of a head fake here. There are a lot of variable assignments in this code. Lots of variable assignments results in a lot of tracing during security code audits. As a variable is set with an untrusted value,it becomes tainted. Following that variable until you find exactly where its being used is crucial in understanding whether a security bug exists or not. Any one of those variable assignments could easily result in a major security vulnerability. In this week’s example,the vulnerable line came before the massive set of variable assignments. Once again,we see PHP_SELF being used to create a URL. Instead of trying to encode the value before using it in markup,the developer chose to remove the reference to PHP_SELF. Developers Solution<?php$easingArray = array(swing,easeInQuad,easeOutQuad,easeInOutQuad,easeInCubic,easeOutCubic,easeInOutCubic,easeInQuart,easeOutQuart,easeInOutQuart,easeInQuint,easeOutQuint,easeInOutQuint,easeInSine,easeOutSine,easeInOutSine,easeInExpo,easeOutExpo,easeInOutExpo,easeInCirc,easeOutCirc,easeInOutCirc,easeInElastic,easeOutElastic,easeInOutElastic,easeInBack,easeOutBack,easeInOutBack,easeInBounce,easeOutBounce,easeInOutBounce);$overlayOpacity = array(0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1);$msArray = array(1,100,200,300,400,500,600,700,800,900,1000);$captions = array('a-title','img-alt','img-title','href','None');?><div class="wrap">-<form method="post"action="<?php echo $_SERVER['PHP_SELF']?>?page=slimbox2options"id="options"><?phpecho wp_nonce_field('update-options','wp_slimbox_wpnonce');?><h2><?php _e('WP Slimbox2 Plugin','wp-slimbox2');?></h2>+ <form method="post"action=""id="options"><?php echo wp_nonce_field('update-options','wp_slimbox_wpnonce');?><h2><?php _e('WP Slimbox2 Plugin','wp-slimbox2');?></h2><?phpif(isset($_POST['action']) &&wp_verify_nonce($_POST['wp_slimbox_wpnonce'],'update-options')){$options->update_option(array('autoload' =>$_POST['wp_slimbox_autoload'],'loop' =>$_POST['wp_slimbox_loop'],'overlayOpacity' =>$_POST['wp_slimbox_overlayOpacity'],'overlayColor' =>$_POST['wp_slimbox_overlayColor'],'overlayFadeDuration' =>$_POST['wp_slimbox_overlayFadeDuration'],'resizeDuration' =>$_POST['wp_slimbox_resizeDuration'],'resizeEasing' =>$_POST['wp_slimbox_resizeEasing'],'initialWidth' =>$_POST['wp_slimbox_initialWidth'],'initialHeight' =>$_POST['wp_slimbox_initialHeight'],'imageFadeDuration' =>$_POST['wp_slimbox_imageFadeDuration'],'captionAnimationDuration' =>$_POST['wp_slimbox_captionAnimationDuration'],'caption' =>array($_POST['wp_slimbox_caption1'],$_POST['wp_slimbox_caption2'],$_POST['wp_slimbox_caption3'],$_POST['wp_slimbox_caption4']),'url' =>$_POST['wp_slimbox_url'],'selector' =>$_POST['wp_slimbox_selector'],'counterText' =>$_POST['wp_slimbox_counterText'],'closeKeys' =>$_POST['wp_slimbox_closeKeys'],'previousKeys' =>$_POST['wp_slimbox_previousKeys'],'nextKeys' =>$_POST['wp_slimbox_nextKeys'],'picasaweb' =>$_POST['wp_slimbox_picasaweb'],'flickr' =>$_POST['wp_slimbox_flickr'],'mobile' =>$_POST['wp_slimbox_mobile'],'maintenance' =>$_POST['wp_slimbox_maintenance'],'cache' =>$_POST['wp_slimbox_cache']));echo '<div id="message"class="updated fade"><p><strong>'.__('Settings Saved','wp-slimbox2').'.</strong></p></div>'}$caption = $options->get_option('caption');function selectionGen(&$option,&$array){foreach($array as $key=>$ms){$selected = ($option != $ms)? '':' selected';echo "<option value='$ms'$selected>".(($ms=='1'&&$array[0]!='0')?__('Disabled','wp-slimbox2'):$ms)."</option>\n"}}?><div style="clear:both;padding-top:5px;"></div><h2><?php _e('Settings','wp-slimbox2');?></h2><table class="widefat"cellspacing="0"id="inactive-plugins-table"><thead><tr><th scope="col"colspan="2"><?php _e('Setting','wp-slimbox2');?></th><th scope="col"><?php _e('Description','wp-slimbox2');?></th></tr></thead><tfoot><tr><th scope="col"colspan="3"><?php _e('Use the various options above to control some of the advanced settings of the plugin','wp-slimbox2');?></th></tr></tfoot><tbody class="plugins"><tr class='inactive'><td class='name'><?php _e('Autoload?','wp-slimbox2');?></td><th scope='row' class='check-column'><input type="checkbox"name="wp_slimbox_autoload"<?php if ($options->get_option('autoload') == 'on') echo ' checked="yes"';?>/></th><td class='desc'><p><?php _e('This option allows the user to automatically activate Slimbox on all links pointing to ".jpg",".jpeg",".png",".bmp"or ".gif". All image links will automatically be grouped together in a gallery according to the selector chosen below. If this isn\'t activated you will need to manually add <b><code>rel="lightbox"</code></b>for individual images or <b><code>rel="lightbox-imagesetname"</code></b>for groups on all links you wish to use the Slimbox effect. <b>Default is Disabled.</b>','wp-slimbox2');?></p></td></tr><tr class='inactive'><td class='name'><?php _e('Enable Picasaweb Integration?','wp-slimbox2');?></td><th scope='row' class='check-column'><input type="checkbox"name="wp_slimbox_picasaweb"<?php if ($options->get_option('picasaweb') == 'on') echo ' checked="yes"';?>/></th><td class='desc'><p><?php _e('This option allows the user to automatically add the Slimbox effect to Picasaweb links when provided an appropriate url (this is separate from the autoload script which only functions on direct image links). <b>Default is Disabled.</b>','wp-slimbox2');?></p></td></tr><tr class='inactive'><td class='name'><?php _e('Enable Flickr Integration?','wp-slimbox2');?></td><th scope='row' class='check-column'><input type="checkbox"name="wp_slimbox_flickr"<?php if ($options->get_option('flickr') == 'on') echo ' checked="yes"';?>/></th><td class='desc'><p><?php _e('This option allows the user to automatically add the Slimbox effect to Flickr links when provided an appropriate url (this is separate from the autoload script which only functions on direct image links). <b>Default is Disabled.</b>','wp-slimbox2');?></p></td></tr><tr class='inactive'><td class='name'><?php _e('Loop?','wp-slimbox2');?></td><th scope='row' class='check-column'><input type="checkbox"name="wp_slimbox_loop"<?php if ($options->get_option('loop') == 'on') echo ' checked="yes"';?>/></th><td class='desc'><p><?php _e('This option allows the user to navigate between the first and last images of a Slimbox gallery group when there is more than one image to display. <b>Default is Disabled.</b>','wp-slimbox2');?></p></td></tr><tr class='inactive'><td class='name'><?php _e('Overlay Opacity','wp-slimbox2');?></td><th scope='row' class='check-column'><select name="wp_slimbox_overlayOpacity"><?php selectionGen($options->get_option('overlayOpacity'),$overlayOpacity);?></select></th><td class='desc'><p><?php _e('This option allows the user to adjust the opacity of the background overlay. 1 is completely opaque,0 is completely transparent. <b>Default is 0.8.</b>','wp-slimbox2');?></p></td></tr><tr class='inactive'><td class='name'><?php _e('Overlay Color','wp-slimbox2');?></td><th scope='row' class='check-column'><input type="text"id="wp_slimbox_overlayColor"name="wp_slimbox_overlayColor"value="<?php echo $options->get_option('overlayColor');?>"size="7"maxlength="7"/><div id="picker"></div></th><td class='desc'><p><?php _e('This option allows the user to set the color of the overlay by selecting your hue from the circle and color gradient from the square. Alternatively you may manually enter a valid HTML color code. The color of the entry field will change to reflect your selected color. <b>Default is #000000.</b>','wp-slimbox2');?></p></td></tr><tr class='inactive'><td class='name'><?php _e('Overlay Fade Duration','wp-slimbox2');?></td><th scope='row' class='check-column'><select name="wp_slimbox_overlayFadeDuration"><?php selectionGen($options->get_option('overlayFadeDuration'),$msArray);?></select></th><td class='desc'><p><?php _e('This option allows the user to adjust the duration of the overlay fade-in and fade-out animations,in milliseconds. <b>Default is 400.</b>','wp-slimbox2');?></p></td></tr><tr class='inactive'><td class='name'><?php _e('Resize Duration','wp-slimbox2');?></td><th scope='row' class='check-column'><select name="wp_slimbox_resizeDuration"><?php selectionGen($options->get_option('resizeDuration'),$msArray);?></select></th><td class='desc'><p><?php _e('This option allows the user to adjust the duration of the resize animation for width and height,in milliseconds. <b>Default is 400.</b>','wp-slimbox2');?></p></td></tr>DetailsAffected Software:Subscribe to Comments Plugin Fixed in Version:2.1 Issue Type:Cross Site Scripting (XSS) Original Code:Found Here DescriptionA familiar symptom here with the same ole result. In the vulnerable code we see a call to $_SERVER['REQUEST_URI']. For some reason,many developers assume REQUEST_URI cannot be tainted and used for XSS. REQUEST_URI will not only include the path to current php file,it will also include any querystring parameters in the URI as well. Here’s a few examples of what REQUEST_URI will return: http://spotthevuln.com/blah/ results in –>/ http://spotthevuln.com/blah//index.php results in –>/blah/index.php http://spotthevuln.com/blah/index.php?qs=value results in –>/blah/index.php?qs=value http://spotthevuln.com/blah/index.php/qs1/qs2 results in –>/blah/index.php/qs1/qs2
As you can see an attacker can easily taint the REQUEST_URI value,using it in XSS attacks. The developers addressed this vulnerability by encoding calls to REQUEST_URI. Developers Solution<?phpfunction show_subscription_checkbox ($id='0'){global $sg_subscribe;sg_subscribe_start();if ( $sg_subscribe->checkbox_shown ) return $id;if ( !$email = $sg_subscribe->current_viewer_subscription_status() ):?><?php ?><?php ?><?php ?><p <?php if ($sg_subscribe->clear_both) echo 'style="clear:both;"';?>class="subscribe-to-comments"> <input type="checkbox"name="subscribe"id="subscribe"value="subscribe"style="width:auto;"<?php if ($sg_subscribe->default_subscribed) echo 'checked="checked"';?>/> <label for="subscribe"><?php echo $sg_subscribe->not_subscribed_text;?></label></p><?php ?><?php elseif ( $email == 'admin' &¤t_user_can('manage_options') ):?><?php ?><?php ?><?php ?><p <?php if ($sg_subscribe->clear_both) echo 'style="clear:both;"';?>class="subscribe-to-comments"><?php echo str_replace('[manager_link]',$sg_subscribe->manage_link($email,true,false),$sg_subscribe->author_text);?></p><?php else:?><?php ?><?php ?><?php ?><p <?php if ($sg_subscribe->clear_both) echo 'style="clear:both;"';?>class="subscribe-to-comments"><?php echo str_replace('[manager_link]',$sg_subscribe->manage_link($email,true,false),$sg_subscribe->subscribed_text);?></p><?php ?><?php endif;$sg_subscribe->checkbox_shown = true;return $id}function show_manual_subscription_form (){global $id,$sg_subscribe,$user_email;sg_subscribe_start();$sg_subscribe->show_errors('solo_subscribe','<div class="solo-subscribe-errors">','</div>',__('<strong>Error:</strong>','subscribe-to-comments'),'<br />');if ( !$sg_subscribe->current_viewer_subscription_status() ):get_currentuserinfo();?><?php ?><?php ?><?php ?>-<form action="http://<?php echo $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ?>"method="post">+<form action="http://<?php echo $_SERVER['HTTP_HOST'] . wp_specialchars($_SERVER['REQUEST_URI']);?>"method="post"><input type="hidden"name="solo-comment-subscribe"value="solo-comment-subscribe"/><input type="hidden"name="postid"value="<?php echo $id;?>"/>-<input type="hidden"name="ref"value="<?php echo 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];?>"/>+<input type="hidden"name="ref"value="<?php echo urlencode('http://' . $_SERVER['HTTP_HOST'] . wp_specialchars($_SERVER['REQUEST_URI']));?>"/><p class="solo-subscribe-to-comments"><?php _e('Subscribe without commenting','subscribe-to-comments');?><br /><label for="solo-subscribe-email"><?php _e('E-Mail:','subscribe-to-comments');?><input type="text"name="email"id="solo-subscribe-email"size="22"value="<?php echo $user_email;?>"/></label><input type="submit"name="submit"value="<?php _e('Subscribe','subscribe-to-comments');?>"/></p></form><?php ?>DetailsAffected Software:WordPress (core) Fixed in Version:1.2 Issue Type:XSS Original Code: Found Here DescriptionLooking at this code made me smile,its about 6 years old. There’s a lot going on here and quite a few issues. The first thing that jumped out at me was the use of $HTTP_POST_FILES. $HTTP_POST_FILES means were working with user controlled files. There are tons of things that can go wrong when dealing with user/attacker controlled files (a list too long to go into here). Lets hope the WordPress devs are on their A-game here. Looking at the patch submitted by the WordPress developers,we see that they changed references to $HTTP_POST_FILES to the superglobal $_FILES. Within the $_FILES array there are a couple indexes that are commonly used. These indexes are: [name] [type] [tmp_name] [error] [size]
Name,type,and size are all controlled by the user/attacker,so the WordPress developers should be wary when dealing with these values. Surprisingly (or unsurprisingly,depending on your point of view),this patch doesn’t contain seem to contain any robust validation of data associated with the uploaded file data. Instead,the defenses put in place here seem to be centered around replacing a poor validation/sanitization routine with a more robust encoding routine which prevents a XSS vulnerability. The replaced sanitization routine and the XSS bug are presented in the following lines: -$imgdesc = str_replace(‘”‘,‘&quot;’,$_POST['imgdesc']); +$imgdesc = htmlentities2($imgdesc); class=”uploadform”value=”<?php echo $imgdesc;?>”/>
What’s surprising is although the WordPress developers prevented this single XSS vulnerability,there is a large number of XSS vulnerabilities in this file. The most obvious symptom is “<?php echo $_REQUEST[] ?>. Additionally,the loose validation of the user uploaded file is concerning,especially with the number of problems that can be encountered when dealing with user controlled files. Maybe the varsity team was on vacation when this patch went in. Developers Solution1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| <?php //Makes sure they choose a file
//print_r($HTTP_POST_FILES); //die();
- $imgalt = (isset($_POST['imgalt'])) ? $_POST['imgalt']:$imgalt; - - $img1_name = (strlen($imgalt)) ? $_POST['imgalt']:$HTTP_POST_FILES['img1']['name']; - $img1_type = (strlen($imgalt)) ? $_POST['img1_type']:$HTTP_POST_FILES['img1']['type']; - $imgdesc = str_replace('"','&quot;',$_POST['imgdesc']); +$imgalt = basename( (isset($_POST['imgalt'])) ? $_POST['imgalt']:'' ); + +$img1_name = (strlen($imgalt)) ? $imgalt:basename( $_FILES['img1']['name'] ); +$img1_type = (strlen($imgalt)) ? $_POST['img1_type']:$_FILES['img1']['type']; +$imgdesc = htmlentities2($imgdesc);
$imgtype = explode(".",$img1_name); $imgtype = strtolower($imgtype[count($imgtype)-1]);
if (in_array($imgtype,$allowed_types) == false) { die(sprintf(__('File %1$s of type %2$s is not allowed.') ,$img1_name,$imgtype)); }
if (strlen($imgalt)) { $pathtofile = get_settings('fileupload_realpath')."/".$imgalt; -$img1 = $_POST['img1']; +$img1 = $_POST['img1']['tmp_name']; } else { $pathtofile = get_settings('fileupload_realpath')."/".$img1_name; -$img1 = $HTTP_POST_FILES['img1']['tmp_name']; +$img1 = $_FILES['img1']['tmp_name']; }
// makes sure not to upload duplicates,rename duplicates $i = 1; $pathtofile2 = $pathtofile; $tmppathtofile = $pathtofile2; $img2_name = $img1_name;
while (file_exists($pathtofile2)) { $pos = strpos($tmppathtofile,'.'.trim($imgtype)); $pathtofile_start = substr($tmppathtofile,0,$pos); $pathtofile2 = $pathtofile_start.'_'.zeroise($i++,2).'.'.trim($imgtype); $img2_name = explode('/',$pathtofile2); $img2_name = $img2_name[count($img2_name)-1]; }
if (file_exists($pathtofile) &&!strlen($imgalt)) { $i = explode(' ',get_settings('fileupload_allowedtypes')); $i = implode(',',array_slice($i,1,count($i)-2)); $moved = move_uploaded_file($img1,$pathtofile2); // if move_uploaded_file() fails,try copy() if (!$moved) { $moved = copy($img1,$pathtofile2); } if (!$moved) { die(sprintf(__("Couldn't upload your file to %s."),$pathtofile2)); } else { chmod($pathtofile2,0666); @unlink($img1); }
//
// duplicate-renaming function contributed by Gary Lawrence Murphy ?> <p><strong><?php __('Duplicate File?') ?></strong></p> <p><b><em><?php printf(__("The filename '%s' already exists!"),$img1_name);?></em></b></p> <p><?php printf(__("Filename '%1\$s' moved to '%2\$s'"),$img1,"$pathtofile2 - $img2_name") ?></p> <p><?php _e('Confirm or rename:') ?></p> <form action="upload.php"method="post"enctype="multipart/form-data"> <input type="hidden"name="MAX_FILE_SIZE"value="<?php echo get_settings('fileupload_maxk') *1024 ?>"/> <input type="hidden"name="img1_type"value="<?php echo $img1_type;?>"/> <input type="hidden"name="img1_name"value="<?php echo $img2_name;?>"/> <input type="hidden"name="img1_size"value="<?php echo $img1_size;?>"/> <input type="hidden"name="img1"value="<?php echo $pathtofile2;?>"/> <input type="hidden"name="thumbsize"value="<?php echo $_REQUEST['thumbsize'];?>"/> <input type="hidden"name="imgthumbsizecustom"value="<?php echo $_REQUEST['imgthumbsizecustom'];?>"/> <?php _e('Alternate name:') ?><br /><input type="text"name="imgalt"size="30"value="<?php echo $img2_name;?>"/><br /> <br /> <?php _e('Description:') ?><br /><input type="text"name="imgdesc"size="30"value="<?php echo $imgdesc;?>"/> <br /> <input type="submit"name="submit"value="<?php _e('Rename') ?>"/> </form> </div> |
DetailsAffected Software:WordPress-to-lead for Salesforce CRM Fixed in Version:1.0.2 Issue Type:Cross Site Scripting (XSS) Original Code: Found Here DescriptionThis week’s vulnerability affected the WordPress-to-lead for Salesforce plugin. Looking at the vulnerable code,we see that stripslashes was applied before echoing attacker controlled content into the HTML markup. Stripslashes was applied in the following lines: $val = strip_tags(stripslashes($_POST[$id])); $content .= “\t”.’<label for=”sf_’.$id.’”>’.esc_html(stripslashes($input['label'])).’:'; $content .= “\t”.’<input type=”submit”value=”‘.esc_attr($submit).’”/>’.”\n”;
Unfortunately,stripslashes doesn’t help protect against XSS. It’s uncertain whether the original developer thought stripslashes would help protect against XSS. Regardless of the developer’s intentions,the example does bring a good principle to light. Developers (and security professionals) should understand what security based APIs provide. It can be difficult to understand which API is most appropriate for various situations. Having guidance for non security focused developers is important. As security professionals,the benefits of an API usage can be obvious. For a non security focused developer,the number of security APIs can be daunting,much less understanding when to call one API versus another. This vulnerability was addressed by using the proper escaping APIs as shown in the patch below. Developers Solution1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| } else if ($is_sidebar &&$options['usecss']) { $content .= '<style type="text/css"> .sidebar form.w2llead{clear:none;text-align:left;} .sidebar .w2linput,#sidebar .w2llabel{float:none;display:inline;} .sidebar .w2llabel.error {color:#f00;} .sidebar .w2llabel {margin:4px 0;} .sidebar .w2linput.text{width:95%;height:18px;margin:4px 0;} .sidebar .w2linput.textarea {width:95%;height:50px;margin:10px 0;} .sidebar .w2linput.submit {margin:10px 0 0 0;} #salesforce{margin:3px 0 0 0;color:#aaa;} #salesforce a{color:#999;} </style>'; } $sidebar = ''; if ($is_sidebar) $sidebar = ' sidebar'; $content .= "\n".'<form method="post">'."\n"; foreach ($options['inputs'] as $id =>$input) { if (!$input['show']) continue; $val = ''; if (isset($_POST[$id])) -$val = strip_tags(stripslashes($_POST[$id])); +$val = esc_attr(strip_tags(stripslashes($_POST[$id])));
$error = ' '; if ($input['error']) $error = ' error ';
-$content .= "\t".'<label for="sf_'.$id.'">'.stripslashes($input['label']).':'; +$content .= "\t".'<label for="sf_'.$id.'">'.esc_html(stripslashes($input['label'])).':'; if ($input['required']) $content .= ' *'; $content .= '</label>'."\n"; if ($input['type'] == 'text') { $content .= "\t".'<input value="'.$val.'"id="sf_'.$id.'"name="'.$id.'"type="text"/><br/>'."\n\n"; } else if ($input['type'] == 'textarea') { $content .= "\t".'<br/>'."\n\t".'<textarea id="sf_'.$id.'"name="'.$id.'">'.$val.'</textarea><br/>'."\n\n"; } } $submit = stripslashes($options['submitbutton']); if (empty($submit)) $submit = "Submit"; -$content .= "\t".'<input type="submit"name="w2lsubmit"value="'.$submit.'"/>'."\n"; +$content .= "\t".'<input type="submit"name="w2lsubmit"value="'.esc_attr($submit).'"/>'."\n"; $content .= '</form>'."\n";
$reqtext = stripslashes($options['requiredfieldstext']); if (!empty($reqtext)) $content .= '<p id="requiredfieldsmsg"><sup>*</sup>'.$reqtext.'</p>'; $content .= '<div id="salesforce"><small>Powered by <a href="http://www.salesforce.com/">Salesforce CRM</a></small></div>'; return $content; }
function submit_salesforce_form($post,$options) { global $wp_version; if (!isset($options['org_id']) || empty($options['org_id'])) return false;
$post['oid'] = $options['org_id']; $post['lead_source'] = $options['source']; $post['debug'] = 0;
// Set SSL verify to false because of server issues. $args = array( 'body' =>$post, 'headers' =>array( 'user-agent' =>'WordPress-to-Lead for Salesforce plugin - WordPress/'.$wp_version.';'.get_bloginfo('url'), ), 'sslverify' =>false, );
$result = wp_remote_post('https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8',$args);
if ($result['headers']['is-processed'] == "true") return true; else return false; } |
|