Saturday, November 21, 2015

PHP static code analysis vs ~1000 top wordpress plugins = 103 vulnerable plugins found


░▒▓█ Introduction


I've been making php static code analysis tool for a while and few months ago I ran it against ~1000 (more or less) top wordpress plugins.

Scanning results were manually verified in my spare time and delivered to official plugins@wordpress.org from 04.07.2015 to 31.08.2015. Most of reported plugins are already patched, some are not. Vulnerable and not patched plugins are already removed from official wordpress plugin repository.

░▒▓█ Results


103 plugins vulnerable with more than 4.000.000 active installations in total (~30.000.000 downloads)

List of reported plugins (original reports contain verification/reproduce sections and urls to plugin wordpress repository entries, where you can also verify changelog) :

  • Cross-Site Scripting (XSS) in Duplicator 0.5.24 [original report - Sat, 15 Aug 2015]
  • Cross-Site Scripting (XSS) in All In One WP Security 3.9.7 [original report - Thu, 13 Aug 2015]
  • Cross-Site Scripting (XSS) in AddThis 5.0.12 [original report - Tue, 11 Aug 2015]
  • Cross-Site Scripting (XSS) in Display Widgets 2.03 [original report - Tue, 11 Aug 2015]
  • Blind SQL injection and XSS in SEO SearchTerms Tagging 2 1.535 [original report - Wed, 8 Jul 2015] NOT PATCHED
  • Blind SQL injection in Pretty Link Lite 1.6.7 [original report - Wed, 8 Jul 2015]
  • Blind SQL injection in WP Statistics 9.4 [original report - Thu, 9 Jul 2015]
  • Cross-Site Scripting (XSS) in My Page Order 4.3 [original report - Thu, 13 Aug 2015] NOT PATCHED
  • Cross-Site Scripting (XSS) in Category Order and Taxonomy Terms Order 1.4.4 [original report - Tue, 18 Aug 2015]
  • Persistent Cross-Site Scripting (XSS) in WP Social Bookmarking Light 1.7.9 [original report - Wed, 19 Aug 2015]
  • Cross-Site Scripting (XSS) in WP Google Fonts v3.1.3 [original report - Wed, 19 Aug 2015]
  • Cross-Site Scripting (XSS) in Easy Table 1.5.2 [original report - Mon, 10 Aug 2015]
  • Cross-Site Scripting (XSS) in My Category Order 4.3 [original report - Thu, 13 Aug 2015] NOT PATCHED
  • Cross-Site Scripting (XSS) in CKEditor for WordPress 4.5.3 [original report - Mon, 31 Aug 2015]
  • Blind SQL injection in Huge IT Slider 2.8.6 [original report - Wed, 22 Jul 2015]
  • Cross-Site Scripting (XSS) in Dynamic Widgets 1.5.10 [original report - Tue, 11 Aug 2015]
  • Cross-Site Scripting (XSS) in Google Language Translator 4.0.9 [original report - Thu, 13 Aug 2015]
  • Cross-Site Scripting (XSS) in JW Player 6 Plugin for Wordpress 2.1.14 [original report - Wed, 19 Aug 2015] NOT PATCHED
  • Persistent Cross-Site Scripting (XSS) in Floating Social Media Icon 2.1 [original report - Wed, 19 Aug 2015]
  • Blind SQL injections in Contact Form Builder 1.0.24 [original report - Tue, 7 Jul 2015]
  • Arbitrary file upload and Cross-Site Scripting (XSS) in Slideshow Gallery 1.5.3 [original report - Thu, 20 Aug 2015]
  • Blind SQL injection in Master Slider 2.5.1 [original report - Thu, 20 Aug 2015]
  • Blind SQL injection and Reflected XSS in WP RSS Multi Importer 3.15 [original report - Wed, 8 Jul 2015] NOT PATCHED
  • Cross-Site Scripting (XSS) in Add Link to Facebook 2.2.7 [original report - Thu, 13 Aug 2015] NOT PATCHED
  • Blind SQL injection in 404 to 301 2.0.2 [original report - Thu, 20 Aug 2015]
  • Cross-Site Scripting (XSS) in Alpine PhotoTile for Instagram 1.2.7.5 [original report - Thu, 20 Aug 2015]
  • Cross-Site Scripting (XSS) in Huge IT Image Gallery 1.5.1 [original report - Thu, 20 Aug 2015]
  • Persistent Cross-Site Scripting (XSS) in Visitor Maps and Who's Online 1.5.8.6 [original report - Thu, 20 Aug 2015]
  • Cross-Site Scripting (XSS) in WP Google Map Plugin 2.3.9 [original report - Thu, 20 Aug 2015]
  • Cross-Site Scripting (XSS) in WP Job Manager 1.23.7 [original report - Thu, 20 Aug 2015]
  • SQL injection (+XSS) in Easy Social Icons 1.2.3.1 [original report - Wed, 22 Jul 2015]
  • Cross-Site Scripting (XSS) in My Link Order 4.3 [original report - Thu, 13 Aug 2015] NOT PATCHED
  • Persistent Cross-Site Scripting (XSS) in WP Database Backup 3.3 [original report - Thu, 20 Aug 2015]
  • Arbitrary file upload and Reflected Cross-Site Scripting (XSS) in Theme Test Drive 2.9 [original report - Thu, 20 Aug 2015]
  • Cross-Site Scripting (XSS) in Subscribe to Comments Reloaded 150611 [original report - Thu, 20 Aug 2015]
  • Cross-Site Scripting (XSS) in SEO Redirection 2.8 [original report - Fri, 21 Aug 2015]
  • Cross-Site Scripting (XSS) in qTranslate-X 3.4.3 [original report - Fri, 21 Aug 2015]
  • Blind SQL injection in Gallery Bank Lite Edition Version 3.0.229 [original report - Fri, 21 Aug 2015]
  • Persistent Cross-Site Scripting (XSS) in Crazy Bone 0.5.5 [original report - Fri, 21 Aug 2015]
  • Persistent Cross-Site Scripting (XSS) in Social Media Widget by Acurax 2.2 [original report - Fri, 21 Aug 2015]
  • Reflected Cross-Site Scripting (XSS) in Anti-spam by CleanTalk 5.21 [original report - Tue, 25 Aug 2015]
  • Blind SQL injection in Smooth Slider 2.6.5 [original report - Wed, 15 Jul 2015]
  • Cross-Site Scripting (XSS) in YITH Maintenance Mode 1.1.4 [original report - Fri, 21 Aug 2015]
  • Multiple SQL injections and XSS in Email Subscribers 2.9 [original report - Mon, 10 Aug 2015]
  • Cross Site Scripting (XSS) in Email newsletter 20.13.6 [original report - Mon, 10 Aug 2015] NOT PATCHED
  • Cross-Site Scripting (XSS) in Easy Pie Coming Soon 1.0.0 [original report - Mon, 10 Aug 2015]
  • Cross-Site Scripting (XSS) in Easy Pie Coming Soon 1.0.0 [original report - Mon, 10 Aug 2015]
  • Cross-Site Scripting (XSS) in Contact Bank Lite Edition 2.0.225 [original report - Thu, 13 Aug 2015]
  • Cross-Site Scripting (XSS) in Kiwi Logo Carousel 1.7.1 [original report - Thu, 13 Aug 2015]
  • Persistent Cross-Site Scripting (XSS) in WP Legal Pages 1.0.1 [original report - Fri, 21 Aug 2015]
  • Cross-Site Scripting (XSS) in WP Crontrol 1.2.3 [original report - Fri, 21 Aug 2015]
  • Cross-Site Scripting (XSS) in Websimon Tables 1.3.4 [original report - Fri, 21 Aug 2015] NOT PATCHED
  • Cross-Site Scripting (XSS) in SEO Rank Reporter 2.2.2 [original report - Mon, 24 Aug 2015] NOT PATCHED
  • Persistent Cross-Site Scripting (XSS) in WP Keyword Link 1.7 [original report - Mon, 24 Aug 2015] NOT PATCHED
  • Cross-Site Scripting (XSS) in Huge IT Portfolio Gallery 1.5.7 [original report - Mon, 24 Aug 2015]
  • Cross-Site Scripting (XSS) in Manual Image Crop 1.10 [original report - Mon, 24 Aug 2015]
  • Cross-Site Scripting (XSS) in iQ Block Country in 1.1.19 [original report - Mon, 24 Aug 2015]
  • SQL injection and Cross-Site Scripting (XSS) in GigPress 2.3.10 [original report - Mon, 24 Aug 2015]
  • Arbitrary file read in Multi Plugin Installer 1.1.0 [original report - Mon, 24 Aug 2015]
  • Persistent Cross-Site Scripting (XSS) in FV Wordpress Flowplayer 6.0.3.3 [original report - Mon, 24 Aug 2015]
  • Persistent Cross-Site Scripting (XSS) in Easy Coming Soon 1.8.1 [original report - Mon, 24 Aug 2015]
  • Cross-Site Scripting (XSS) in Contact Form Manager 1.4.1 [original report - Mon, 24 Aug 2015] NOT PATCHED
  • Blind SQL injection in WordPress Meta Robots 2.1 [original report - Tue, 25 Aug 2015] NOT PATCHED
  • Cross-Site Scripting (XSS) in Smart Slider 2 2.3.11 [original report - Wed, 26 Aug 2015]
  • Cross-Site Scripting (XSS) in Soundcloud is Gold 2.3.1 [original report - Wed, 26 Aug 2015]
  • Blind SQL injection in Contact Form Maker 1.7.30 [original report - Wed, 8 Jul 2015]
  • Cross-Site Scripting (XSS) in Plugin Central 2.5 [original report - Tue, 25 Aug 2015]
  • Blind SQL injection in yet another stars rating 0.9.0 [original report - Mon, 6 Jul 2015]
  • Blind SQL injection in smart manager for wp e commerce 3.9.6 [original report - Wed, 8 Jul 2015]
  • Blind SQL injection and CSRF for logged administrators in awesome filterable portfolio 1.8.6 [original report - Tue, 7 Jul 2015]
  • Blind SQL injections in WP Shop 3.4.3.15 [original report - Wed, 8 Jul 2015]
  • Cross-Site Scripting (XSS) in Job Manager 0.7.24 [original report - Tue, 25 Aug 2015]
  • Persistent Cross-Site Scripting (XSS) in "Post video players, slideshow albums, photo galleries and music / podcast playlist" 1.136 [original report - Tue, 25 Aug 2015]
  • Arbitrary file modification in Child Theme Creator by Orbisius 1.2.6 [original report - Wed, 8 Jul 2015]
  • SQL injection in WP-Stats-Dashboard 2.9.4 [original report - Tue, 25 Aug 2015] NOT PATCHED
  • Cross-Site Scripting (XSS) in WP Page Widget 2.7 [original report - Tue, 25 Aug 2015]
  • Blind SQL injection in wti like post 1.4.2 [original report - Sun, 5 Jul 2015]
  • SQL injection in Huge IT Google Map 2.2.5 [original report - Wed, 8 Jul 2015] NOT PATCHED
  • Blind SQL injection and Reflected XSS vulnerabilities in broken link manager plugin 0.4.5 [original report - Sat, 4 Jul 2015]
  • Blind SQL injection in Microblog Poster 1.6.0 [original report - Wed, 22 Jul 2015]
  • SQL injection and Cross-Site Scripting (XSS) in GoCodes 1.3.5 [original report - Tue, 25 Aug 2015] NOT PATCHED
  • Blind SQL injections in Auto Affiliate Links 4.9.9.4 [original report - Wed, 15 Jul 2015]
  • Cross-Site Scripting (XSS) in WP Widget Cache 0.26 [original report - Tue, 25 Aug 2015] NOT PATCHED
  • SQL injections and XSS in SendPress Newsletters 1.1.7.21 [original report - Thu, 23 Jul 2015]
  • Cross-Site Scripting (XSS) in Email Users 4.7.5 [original report - Mon, 10 Aug 2015]
  • Persistent Cross-Site Scripting (XSS) in Social Share Button 2.1 [original report - Tue, 25 Aug 2015] NOT PATCHED
  • Cross-Site Scripting (XSS) in Social Locker | BizPanda 4.2.0 [original report - Tue, 25 Aug 2015]
  • Cross Site Scripting (XSS) in Email Encoder Bundle - Protect Email Address 1.4.1 [original report - Mon, 10 Aug 2015]
  • Persistent Cross-Site Scripting (XSS) in Page Restrict 2.2.1 [original report - Tue, 25 Aug 2015]
  • Persistent Cross-Site Scripting (XSS) in Multicons 2.1 [original report - Tue, 25 Aug 2015]
  • Persistent Cross-Site Scripting (XSS) in PlugNedit Adaptive Editor 5.2.0 [original report - Tue, 25 Aug 2015]
  • Blind SQL injection in WooCommerce Abandon Cart Lite Plugin 1.7 [original report - Wed, 15 Jul 2015]
  • Persistent XSS in Broken Link manager Ver 0.5.5 [original report - Thu, 16 Jul 2015]
  • Blind SQL injections in Quiz Master Next 4.4.2 [original report - Thu, 16 Jul 2015]
  • Cross-Site Scripting (XSS) in Role Scoper 1.3.64 [original report - Wed, 26 Aug 2015]
  • Blind SQL injections in NEX-Forms 4.0 [original report - Thu, 16 Jul 2015]
  • Cross-Site Scripting (XSS) in Ad Inserter 1.5.5 [original report - Thu, 13 Aug 2015]
  • Cross-Site Scripting (XSS) in Olevmedia Shortcodes 1.1.8 [original report - Tue, 25 Aug 2015]
  • Blind SQL injection in Booking System (+WooCommerce) 2.0 [original report - Tue, 7 Jul 2015]
  • Blind SQL injections in Plgumatter Optin Feature Box 2.0.13 [original report - Thu, 16 Jul 2015]
  • Blind SQL injection in WR ContactForm 1.1.9 [original report - Thu, 9 Jul 2015]
  • Cross-Site Scripting (XSS) in Simple Fields 1.4.10 [original report - Tue, 25 Aug 2015]
  • Blind SQL injections, XSS and more in wp live chat support 4.3.5 [original report - Mon, 6 Jul 2015]

Some notes:

Without magic_quotes_gpc (wordpress "emulate" it anyway when it's off) it will be some more exploitable SQLi vulnerabilities.

I'm also pretty sure that there are some vulnerabilities in reports that I missed, or just thought that they were unexploitable.

Because of low resources limits (like memory limit ~3GB) many plugins from top 1000 list didn't get 100% code coverage.

░▒▓█ What about CVE identifiers?


I've sent bulk request to cve-assign@mitre.org recently. No response so far.

░▒▓█ Static code analysis tool and some hilights


I used own PhpSourcerer static code analysis tool, which is still in development. You can try PhpSourcerer yourself on php-grinder.com (current limits: 2GB Ram, 15 minutes execution time). It has nice web-ui instead of raw text file reports:





I show you some details about reported vulnerabilities to demonstrate what this tool is capable of.


◼ Reflected Cross-Site Scripting (XSS) in Simple Fields 1.4.10


Description: Authenticated users (like subscribers) can inject html/js code (there is no CSRF protection!)

Some urls: Sent report | Original project sources | PhpSourcerer output

This is a simple example, so I guess it doesn't need explanation:
...

function field_type_post_dialog_load() {

    global $sf;

    $arr_enabled_post_types = isset($_POST["arr_enabled_post_types"]) ? $_POST["arr_enabled_post_types"] : array();
    $str_enabled_post_types = isset($_POST["str_enabled_post_types"]) ? $_POST["str_enabled_post_types"] : "";
    $additional_arguments = isset($_POST["additional_arguments"]) ? $_POST["additional_arguments"] : "";
    $existing_post_types = get_post_types(NULL, "objects");
    $selected_post_type = isset($_POST["selected_post_type"]) ? (string) $_POST["selected_post_type"] : "";

    if (empty($arr_enabled_post_types)) {
      $arr_enabled_post_types = explode(",", $str_enabled_post_types);
    }

    /*echo "<br>selected_post_type: $selected_post_type";
    echo "<br>str_enabled_post_types: $str_enabled_post_types";
    echo "<br>enabled post types:"; print_r($arr_enabled_post_types);*/

    // If no post type is selected then don't show any posts
    if (empty($arr_enabled_post_types)) {
      _e("<p>No post type is selected. Please at at least one post type in Simple Fields.</p>", "simple-fields");
      exit;
    }
    ?>

    <?php if (count($arr_enabled_post_types) > 1) { ?>
      <p>Show posts of type:</p>
      <ul class="simple-fields-meta-box-field-group-field-type-post-dialog-post-types">
        <?php
        $loopnum = 0;
        foreach ($existing_post_types as $key => $val) {
          if (!in_array($key, $arr_enabled_post_types)) {
            continue;
          }
          if (empty($selected_post_type) && $loopnum == 0) {
            $selected_post_type = $key;
          }
          $class = "";
          if ($selected_post_type == $key) {
            $class = "selected";
          }
          printf("\n<li class='%s'><a href='%s'>%s</a></li>", $class, "$key", $val->labels->name);
          $loopnum++;
        }
      ?>
      </ul>
      <?php
    } else {
      $selected_post_type = $arr_enabled_post_types[0];
      ?>
      <p>Showing posts of type: <a href="<?php echo $selected_post_type; ?>"><?php echo $existing_post_types[$selected_post_type]->labels->name; ?></a></p>
      <?php
    } ?>

...



◼ Blind SQL injection in smart manager for wp e commerce 3.9.6


Description: Unauthenticated remote attackers can execute arbitrary SQL commands.

Some urls: Sent report | Original project sources | PhpSourcerer output

/smart-manager-for-wp-e-commerce/sm/woo-json.php:
<?php 

ob_start();

...

// For insert updating product in woo.
if (isset ( $_POST ['cmd'] ) && $_POST ['cmd'] == 'saveData') {

...

  if ( $_POST['active_module'] == "Coupons" ) {

...

  } else {
    $result = woo_insert_update_data ( $_POST );
  }
...
woo_insert_update_data() :
...

function woo_insert_update_data($post) {
  global $wpdb,$woocommerce;
    $_POST = $post;  

      // Fix: PHP 5.4
  $editable_fields = array(
    '_billing_first_name' , '_billing_last_name' , '_billing_email', '_billing_address_1', '_billing_address_2', '_billing_city', '_billing_state',
    '_billing_country','_billing_postcode', '_billing_phone',
    '_shipping_first_name', '_shipping_last_name', '_shipping_address_1', '_shipping_address_2',
    '_shipping_city', '_shipping_state', '_shipping_country','_shipping_postcode', 'order_status'
  );
    $new_product = json_decode($_POST['edited']);

  $edited_prod_ids = array();
  $edited_prod_slug = array();

  if (!empty($new_product)) {
    foreach($new_product as $product) {
      $edited_prod_ids[] = $product->id;
    }
  }

  //Code for getting the product slugs
  if ( !empty($edited_prod_ids) ) {
    $query_prod_slug = "SELECT id, post_name
              FROM {$wpdb->prefix}posts
              WHERE id IN (".implode(",",$edited_prod_ids).")";
    $results_prod_slug = $wpdb->get_results($query_prod_slug, 'ARRAY_A');
    $prod_slug_rows = $wpdb->num_rows;

...
So we can inject our payload in valid json variable, like in verification example in sent report:
curl --request POST  --data "cmd=saveData&edited=[{\"id\":\" 1) union select sleep(10),2; -- -\"}]" http://localhost/wp-content/plugins/smart-manager-for-wp-e-commerce/sm/woo-json.php



◼ Reflected Cross-Site Scripting (XSS) in SEO Redirection 2.8


Description: Authenticated administrators can inject html/js code (there is no CSRF protection).

Some urls: Sent report | Original project sources | PhpSourcerer output

/options/option_page_post_redirection_list.php:
<?php 

global $wpdb,$table_prefix,$util;
$table_name = $table_prefix . 'WP_SEO_Redirection';

  if($util->get('del')!='')
  {
    $delid=intval($util->get('del'));
    $wpdb->query(" delete from $table_name where ID='$delid' ");  
    
    if($util->there_is_cache()!='') 
    $util->info_option_msg("You have a cache plugin installed <b>'" . $util->there_is_cache() . "'</b>, you have to clear cache after any changes to get the changes reflected immediately! ");

    $SR_redirect_cache = new clogica_SR_redirect_cache();
    $SR_redirect_cache->free_cache();
  }
  
  $rlink=$util->get_current_parameters(array('del','search','page_num','add','edit'));
?>
<br/>

<script type="text/javascript">

...

</script>

<div class="link_buttons">
<table border="0" width="100%">
  <tr>
    <td width="110"><a href="<?php echo $rlink?>&add=1"><div class="add_link">Add New</div></a></div></td>
    <td align="right">
    <input onkeyup="if (event.keyCode == 13) go_search();" style="height: 30px;" id="search" type="text" name="search" value="<?php echo $util->get('search')?>" size="40">
    <a onclick="go_search()" href="#"><div class="search_link">Search</div></a> 
$util is object of "clogica_util" class (seo-redirection.php):
<?php
/*
...
*/

require_once ('common/controls.php');
require_once ('custom/controls.php');
require_once ('custom/controls/cf.SR_redirect_cache.class.php');

if(!defined('WP_SEO_REDIRECTION_OPTIONS'))
{
  define( 'WP_SEO_REDIRECTION_OPTIONS', 'wp-seo-redirection-group' );
}

if(!defined('WP_SEO_REDIRECTION_VERSION'))
{
  define( 'WP_SEO_REDIRECTION_VERSION', '2.8');
}

$util= new clogica_util();
$util->set_option_gruop(WP_SEO_REDIRECTION_OPTIONS);
...
Finally lets look how clogica_util::get() looks like:
...

public function get($key,$type='text')
{
  if(array_key_exists($key,$_GET))
  {
      $unsafe_val=$_GET[$key];
        return $this->sanitize_req($unsafe_val,$type);    
  }
  else
  {
      return '';
  }
}

...

public function sanitize_req($unsafe_val,$type='text')
{
   switch ($type) {
     case 'text': return sanitize_text_field($unsafe_val);
     break;
     
     case 'int': return intval($unsafe_val);
     break;
     
     case 'email': return sanitize_email($unsafe_val);
     break;
     
     case 'filename': return sanitize_file_name($unsafe_val);
     break;
     
     case 'title': return sanitize_title($unsafe_val);
     break;
        
     default:
        return sanitize_text_field($unsafe_val);
     
     }
}

...
Yep. Wordpress sanitize_text_field() doesn't prevent from succesful XSS exploitation in html tag attribute.


◼ Reflected Cross-Site Scripting (XSS) in Display Widgets 2.03


Description: Authenticated users (like subscribers) can inject html/js code (there is no CSRF protection!).

Some urls: Sent report | Original project sources | PhpSourcerer output

Lets look at the DWPlugin::show_widget_options() method (invokes by http://localhost/wp-admin/admin-ajax.php?action=dw_show_widget)
...
    function show_widget_options() {
        $instance = htmlspecialchars_decode(nl2br(stripslashes($_POST['opts'])));
        $instance = json_decode($instance, true);
        $this->id_base = $_POST['id_base'];
        $this->number = $_POST['widget_number'];
        
        $new_instance = array();
        $prefix = 'widget-'. $this->id_base .'['. $this->number .'][';
        foreach ( $instance as $k => $v ) {
            $n = str_replace( array( $prefix, ']'), '', $v['name']);
            $new_instance[$n] = $v['value'];
        }

        self::show_hide_widget_options($this, '', $new_instance);
        die();
    }
...
As we can see we have two variables assigned to object properties, and then another method (show_hide_widget_options) is called with $this argument. DWPlugin::show_hide_widget_options():
...
    function show_hide_widget_options($widget, $return, $instance) {
        self::register_globals();
    
        $wp_page_types = self::page_types();
            
        $instance['dw_include'] = isset($instance['dw_include']) ? $instance['dw_include'] : 0;
        $instance['dw_logged'] = self::show_logged($instance);
        $instance['other_ids'] = isset($instance['other_ids']) ? $instance['other_ids'] : '';
?>   
    <p>
        <label for="<?php echo $widget->get_field_id('dw_include'); ?>"><?php _e('Show Widget for:', 'display-widgets') ?></label>
        <select name="<?php echo $widget->get_field_name('dw_logged'); ?>" id="<?php echo $widget->get_field_id('dw_logged'); ?>" class="widefat">
            <option value=""><?php _e('Everyone', 'display-widgets') ?></option>
            <option value="out" <?php echo selected( $instance['dw_logged'], 'out' ) ?>><?php _e('Logged-out users', 'display-widgets') ?></option>
            <option value="in" <?php echo selected( $instance['dw_logged'], 'in' ) ?>><?php _e('Logged-in users', 'display-widgets') ?></option>
        </select>
    </p>

     <p>
     <select name="<?php echo $widget->get_field_name('dw_include'); ?>" id="<?php echo $widget->get_field_id('dw_include'); ?>" class="widefat">
...
And finally get_field_id method and get_field_name:
...
    function get_field_name($field_name) {
  return 'widget-' . $this->id_base . '[' . $this->number . '][' . $field_name . ']';
 }
    
 function get_field_id($field_name) {
  return 'widget-' . $this->id_base . '-' . $this->number . '-' . $field_name;
 }
...
$this->id_base and $this->number were assigned at the beggining in DWPlugin::show_widget_options method.


◼ Persistent Cross-Site Scripting (XSS) in FV Wordpress Flowplayer 6.0.3.3


Description: Authenticated administrators can store html/js code in plugin configuration values (there is no CSRF protection!)

Some urls: Sent report | Original project sources | PhpSourcerer output

First lets look at fv_wp_flowplayer_admin_init() function:
...
function fv_wp_flowplayer_admin_init() {
 if( isset($_GET['type']) ) {
  if( $_GET['type'] == 'fvplayer_video' || $_GET['type'] == 'fvplayer_video_1' || $_GET['type'] == 'fvplayer_video_2' || $_GET['type'] == 'fvplayer_mobile' ) {
   $_GET['post_mime_type'] = 'video';
  }
  else if( $_GET['type'] == 'fvplayer_splash' || $_GET['type'] == 'fvplayer_logo' ) {
   $_GET['post_mime_type'] = 'image';
  }
  }
  
  if( isset($_POST['fv-wp-flowplayer-submit']) ) {
   global $fv_fp;
   if( method_exists($fv_fp,'_set_conf') ) {
   $fv_fp->_set_conf();    
  } else {
   echo 'Error saving FV Flowplayer options.';
  }
 }

  global $fv_fp;
 ...
As we can see we execute _set_conf() method on $fv_wp object when we send fv-wp-flowplayer-submit in POST. $fv_fp is global object of flowplayer_frontend class defined in flowplayer.php main file.
...
$fv_wp_flowplayer_ver = '2.3.17';
$fv_wp_flowplayer_core_ver = '5.5.2';

include( dirname( __FILE__ ) . '/includes/extra-functions.php' );
if( file_exists( dirname( __FILE__ ) . '/includes/module.php' ) ) {
  include( dirname( __FILE__ ) . '/includes/module.php' );
}

include( dirname( __FILE__ ) . '/models/checker.php' );
$FV_Player_Checker = new FV_Player_Checker();

include_once(dirname( __FILE__ ) . '/models/flowplayer.php');
include_once(dirname( __FILE__ ) . '/models/flowplayer-frontend.php');
$fv_fp = new flowplayer_frontend();

if( is_admin() ) {
 include( dirname( __FILE__ ) . '/controller/backend.php' );
  
  register_deactivation_hook( __FILE__, 'flowplayer_deactivate' );

} 
 
include( dirname( __FILE__ ) . '/controller/frontend.php' );
require_once( dirname( __FILE__ ) . '/controller/shortcodes.php');
$fv_fp->_set_conf() method is not really belongs to "flowplayer_frontend" class but to "flowplayer" that "flowplayer_frontend" is extending:
...
class flowplayer_frontend extends flowplayer {
...
flowplayer::_set_conf():
...
 public function _set_conf() {
    $aNewOptions = $_POST;
    $sKey = $aNewOptions['key'];

    foreach( $aNewOptions AS $key => $value ) {
      if( is_array($value) ) {
        $aNewOptions[$key] = $value;
      } else if( !in_array( $key, array('amazon_region', 'amazon_bucket', 'amazon_key', 'amazon_secret', 'font-face', 'ad', 'ad_css') ) ) {
        $aNewOptions[$key] = trim( preg_replace('/[^A-Za-z0-9.:\-_\/]/', '', $value) );
      } else {
        $aNewOptions[$key] = stripslashes($value);
      }
      if( (strpos( $key, 'Color' ) !== FALSE )||(strpos( $key, 'canvas' ) !== FALSE)) {
        $aNewOptions[$key] = '#'.strtolower($aNewOptions[$key]);
      }
    }
    $aNewOptions['key'] = trim($sKey);
    $aOldOptions = is_array(get_option('fvwpflowplayer')) ? get_option('fvwpflowplayer') : array();
    
    if( isset($aNewOptions['db_duration']) && $aNewOptions['db_duration'] == "true" && ( !isset($aOldOptions['db_duration']) || $aOldOptions['db_duration'] == "false" ) ) {
      global $FV_Player_Checker;
      $FV_Player_Checker->queue_add_all();
    }
    
    if( !isset($aNewOptions['pro']) || !is_array($aNewOptions['pro']) ) {
      $aNewOptions['pro'] = array();
    }
    
    if( !isset($aOldOptions['pro']) || !is_array($aOldOptions['pro']) ) {
      $aOldOptions['pro'] = array();
    }    
 
    
    $aNewOptions['pro'] = array_merge($aOldOptions['pro'],$aNewOptions['pro']);
    $aNewOptions = array_merge($aOldOptions,$aNewOptions);
    $aNewOptions = apply_filters( 'fv_flowplayer_settings_save', $aNewOptions, $aOldOptions );
    update_option( 'fvwpflowplayer', $aNewOptions );
    $this->conf = $aNewOptions;    
    
    $this->css_writeout();
           
    return true;  
  }
...
As we can see we override plugin options, that is why we can inject XSS payload in fv_flowplayer_admin_default_options():
...
function fv_flowplayer_admin_default_options() {
 global $fv_fp;
?>
 <table class="form-table2">

...      

  <tr>
   <td><label for="width">Default video size [px]:</label></td>
   <td colspan="2">      
    <label for="width">W:</label> <input type="text" class="small" name="width" id="width" value="<?php echo trim($fv_fp->conf['width']); ?>" />  
    <label for="height">H:</label> <input type="text" class="small" name="height" id="height" value="<?php echo trim($fv_fp->conf['height']); ?>" />       
   </td>
  </tr>      
  <tr>
   <td><label for="googleanalytics">Google Analytics ID:</label></td>
   <td colspan="3"><input type="text" name="googleanalytics" id="googleanalytics" value="<?php echo trim($fv_fp->conf['googleanalytics']); ?>" /></td>
  </tr>
  <tr>
   <td><label for="key">Commercial License Key:</label></td>
   <td colspan="3"><input type="text" name="key" id="key" value="<?php echo trim($fv_fp->conf['key']); ?>" /></td>
  </tr>
...



◼ Blind SQL injection in Master Slider 2.5.1


Description: Authenticated users (like editors) can execute arbitrary sql commands (there is no CSRF protection)

Some urls: Sent report | Original project sources | PhpSourcerer output

I'll just show you just the flow without commenting (pay attention to orderby parameter/variables). We start by looking at /master-slider/admin/views/slider-dashboard/list-sliders.php file:
<?php
    msp_get_panel_header();

    // Display sliders list
 $slider_table_list = new MSP_List_Table();
 $slider_table_list->prepare_items(); 
 $slider_table_list->display(); 
MSP_List_Table::prepare_items() :
...
 function prepare_items() {

  $columns  = $this->get_columns();
  $hidden  = array();
  $sortable  = $this->get_sortable_columns();
   
  $this->_column_headers = array( $columns, $hidden, $sortable );
  
  $this->process_bulk_action();

  $perpage   = (int) apply_filters( 'masterslider_admin_sliders_per_page', 10 );
  $current_page  = $this->get_pagenum();
  $orderby   = 'ID';
  $order    = 'DESC';
  $total_items  =  $this->get_total_count();


  $this->items  = $this->get_records( $perpage, $current_page, $orderby, $order );
  // echo '
'; print_r( $this->items ); echo '
'; // tell the class the total number of items and how many items to show on a page $this->set_pagination_args( array( 'total_items' => $total_items, 'per_page' => $perpage )); } ...
MSP_List_Table::get_total_count() :
...
 function get_total_count(){
  global $mspdb;
  
  $all_items = $this->get_records( 0 );
  return count( $all_items );
 }
...
MSP_List_Table::get_records() :
...
 function get_records( $perpage = 20, $paged  = 1, $orderby = 'ID', $order = 'DESC', $where = "status='published'" ){
  global $mspdb;
  
  $offset  = ( (int)$paged - 1 ) * $perpage;
  $orderby = isset( $_REQUEST['orderby'] ) ? $_REQUEST['orderby'] : 'ID';
  $order   = isset( $_REQUEST['order'] ) ? $_REQUEST['order'] : 'ASC';
  
  $search  = isset( $_REQUEST['s'] ) ? " AND title LIKE '%%" . $_REQUEST['s'] . "%%'" : '';

  return $mspdb->get_sliders( $perpage, $offset, $orderby, $order, $where.$search );
 }
...
MSP_DB::get_sliders() :
...
 public function get_sliders( $perpage = 0, $offset  = 0, $orderby = 'ID', $sort = 'DESC', $where = "status='published'" ) {
  
  // pull mulitple row results from sliders table
  if( ! $results = $this->get_sliders_list( $perpage, $offset, $orderby, $sort, $where ) ){
   return;
  }

  // map through some fields and unserialize values if some data fields are serialized
  foreach ($results as $row_index => $row) {
   $results[$row_index] = $this->maybe_unserialize_fields($row);
  }

  return $results;
 }
...
MSP_DB::get_sliders_list() :
...
 public function get_sliders_list( $perpage = 0, $offset  = 0, $orderby = 'ID', $order = 'DESC', $where = "status='published'" ) {
  global $wpdb;

  $args = array(
   'perpage' => $perpage,
   'offset'  => $offset,
   'orderby' => $orderby,
   'order'   => $order,
   'where'   => $where
  );
  
  return $this->ms_query( $args );
 }
...
And finally MSP_DB::ms_query() where actual SQL injection takes place:
...
 public function ms_query( $args = array() ) {
  global $wpdb;

  $default_args = array(
   'perpage' => 0,
   'offset'  => 0,
   'orderby' => 'ID',
   'order'   => 'DESC',
   'where'   => "status='published'",
   'like'    => ''
  );

  $args = wp_parse_args( $args, $default_args );


  // convert perpage type to number
  $limit_num = (int) $args['perpage'];

  // convert offset type to number
  $offset_num = (int) $args['offset'];

  // remove limit if limit number is set to 0
  $limit  = ( 1 > $limit_num ) ? '' : 'LIMIT '. $limit_num; 

  // remove offect if offset number is set to 0
  $offset = ( 0 == $offset_num )? '' : 'OFFSET '. $offset_num; 

  // add LIKE if defined
  $like  = empty( $args['like'] ) ? '' : 'LIKE '. $args['like']; 

  $where = empty( $args['where'] ) ? '' : 'WHERE '. $args['where']; 

  // sanitize sort type
  $order   = strtolower( $args['order'] ) === 'desc' ? 'DESC' : 'ASC';
  $orderby = $args['orderby'];

  $sql = "
   SELECT *
   FROM {$this->sliders}
   $where
   ORDER BY $orderby $order
   $limit 
   $offset
   ";
  
  return $wpdb->get_results( $sql, ARRAY_A );
 }
...


░▒▓█ Bonus: funny mistake in validation


Plugin: Visitor Maps and Who's Online 1.5.8.6

Idea was good, but something went wrong :-)
function view_whos_been_online() {

...

  $show = (isset($wo_prefs_arr['show'])) ? $wo_prefs_arr['show'] : 'none';
  if ( isset($_GET['show']) && in_array($_GET['show'], array('none','all','bots','guests')) ) {
    $wo_prefs_arr['show'] = $_GET['show'];
    $show = $_GET['show'];
  }

...

  $sort_by = (isset($wo_prefs_arr['sort_by'])) ? $wo_prefs_arr['sort_by'] : 'time';
  if ( isset($_GET['sort_by']) && array('who','visits','time','ip','location','url') ) {
    $wo_prefs_arr['sort_by'] = $_GET['sort_by'];
    $sort_by = $_GET['sort_by'];
  }

...

  $order = (isset($wo_prefs_arr['order'])) ? $wo_prefs_arr['order'] : 'desc';
  if ( isset($_GET['order']) && array('desc','asc') ) {
   // bots
    $wo_prefs_arr['order'] = $_GET['order'];
    $order = $_GET['order'];
  }
...

90 comments:

  1. Replies
    1. IEEE Final Year projects Project Centers in India are consistently sought after. Final Year Students Projects take a shot at them to improve their aptitudes, while specialists like the enjoyment in interfering with innovation. For experts, it's an alternate ball game through and through. Smaller than expected IEEE Final Year project centers ground for all fragments of CSE & IT engineers hoping to assemble. Final Year Projects for CSE It gives you tips and rules that is progressively critical to consider while choosing any final year project point.

      JavaScript Online Training in India

      JavaScript Training in India

      The Angular Training covers a wide range of topics including Components, Angular Directives, Angular Services, Pipes, security fundamentals, Routing, and Angular programmability. The new Angular TRaining will lay the foundation you need to specialise in Single Page Application developer. Angular Training

      Delete
  2. Just a suggestion, but this list would be much more useful to most people if you listed the plugin name first and then the type of vulnerability, and then alphabetized the list.

    ReplyDelete
  3. Very nice. The static code analysis tools for PHP are pretty old and useless at this point, and it nice to see someone working to revitalize the area. Have you considered open sourcing your tool? (Possibly through OWASP?)

    ReplyDelete
    Replies
    1. Source code should be published soon or later, because the main purpose of this tool was to inject it in "Continuous Integration" chain. However, codebase is still messy with many experimental ideas and I just don't want to publish it now as it is.

      Delete
    2. On the other hand, publishing it even before your code has "production-grade" quality would still be benefical to a lot ot people, and it would also be the opportunity to have the community help you tidy it up. "Publish early, release often" ;)

      Delete
  4. Looks like Plugin Central has been patched

    ReplyDelete
    Replies
    1. P.S. We've added *all* of these to https://wpvulndb.com with links back to this post :)

      (patched ones won't show on front page but are in the DB if you look at individual plugin pages)

      Delete
    2. Great! But there are some wrong dates for "Publicly Published" fields (like in https://wpvulndb.com/vulnerabilities/8325). Public disclosure was 21.11.2015 for all plugins affected.

      Delete
  5. This comment has been removed by a blog administrator.

    ReplyDelete
  6. This comment has been removed by a blog administrator.

    ReplyDelete
  7. This comment has been removed by a blog administrator.

    ReplyDelete
  8. This comment has been removed by a blog administrator.

    ReplyDelete
  9. This comment has been removed by a blog administrator.

    ReplyDelete
  10. This comment has been removed by a blog administrator.

    ReplyDelete
  11. This comment has been removed by a blog administrator.

    ReplyDelete
  12. This comment has been removed by a blog administrator.

    ReplyDelete
  13. This comment has been removed by a blog administrator.

    ReplyDelete
  14. This comment has been removed by a blog administrator.

    ReplyDelete
  15. This comment has been removed by a blog administrator.

    ReplyDelete
  16. This comment has been removed by a blog administrator.

    ReplyDelete
  17. I'm not smart english let alone about computer program but your blog very good thank you

    ReplyDelete
  18. This comment has been removed by a blog administrator.

    ReplyDelete
  19. Please release your tool on github. The PHP static analysis tools OWASP recommend flag false positives that your tool didn't as it is written for Wordpress and I'm guessing picks up on functions like sanatize_email and esc_html

    ReplyDelete
  20. Еhe great work you have developed. If you are new, I advise you to consult professionals who will make you a site or allow you to choose a template for your site in the category go here wordpress themes blog

    ReplyDelete
  21. Customer service for me caring for their requirements and helping them and is currently helping anyone who walks into an establishment. Customer service is assisting anyone and meeting with their needs and wants. Good customer-oriented service is just the standard customer-oriented service that everyone is giving to that customer. Good customer-oriented service is if you go out realizing that everything was taken care of with no doubts. Getting individual, helping others the very best that you can. If You Would like to learn More Concerning this topic please Test This out urlhttps://servicecenterguru.com

    ReplyDelete
  22. In this tutorial we'll go through how to get Wordpress running on your own PC (running Windows) so you have your own personal Wordpress installation to experiment with or learn from.https://medijo.lt/etiketes/

    ReplyDelete
  23. If you need website development and design for your business or product visit ogeninfo.
    Website Designing Company in Delhi

    ReplyDelete
  24. For Mutual Fund Advisor and best mutual fund investment scheme visit mutualfundwala.
    Best Performing Mutual Fund

    ReplyDelete
  25. Nice Information, For the best service of Freight Forwarders and Shipping Company visit YhCargoindia at.
    Freight Forwarders in India

    ReplyDelete
  26. This content was really impressive, thank you so much for sharing with us.
    Audio Engineering Courses

    ReplyDelete
  27. Really Nice blog, thank you so much for sharing with us. Mobile Apps Development Company Delhi

    ReplyDelete
  28. World Cup is started from 30th May 2019 to 14th July 2019. This world cup is hosted by England.
    In this World cup 10 teams is participated & total 48 matches is going to played including 2 semi finals and final.
    India and England are strong contenders & favourite
    Cricbuzz
    Online betting
    Who will win
    Who will win today
    Cricket match prediction
    Digital Marketing Institute in Delhi

    ReplyDelete
  29. The previously mentioned advantages alongside different other have made PHP most valuable and famous language for creating dynamic sites. CakePHP Application Development

    ReplyDelete
  30. Your work is very good and I appreciate you and hopping for some more informative posts baby food maker https://bestbabyfoodmaker.com/

    ReplyDelete
  31. The PHP content itself is excluded in the HTML that is sent to the program, so the PHP code is imperceptible and secure to the client.Why use Laravel

    ReplyDelete
  32. Best Data Science & Machine Learning with Python training institute VisionHook in Noida, Noida, provides real-time and placement oriented Data Science & Machine Learning with Python training in Noida. VisionHook provide the Best Data Science & Machine Learning with Python training course in Noida.

    http://www.visionhook.in/best-data-science-and-machine-learning-with-python-training-in-noida.html

    ReplyDelete
  33. I am really impressed with your blog article, such great & useful knowledge you mentioned here. Your post is very informative. Also check out the best web development company in Kolkata | web hosting company in Kolkata | hotel management colleges in Kolkata

    ReplyDelete
  34. I never comment on blogs but your article is so best that I never stop myself to say something about it. You’re amazing Man, I like it wp database
    ... Keep it up

    ReplyDelete
  35. Bagi banyak wanita, mengakhiri kehamilan adalah keputusan yang sulit. Bila wanita tersebut tidak dapat mendiskusikan aborsi atau alternatif dengan penyedia layanan kesehatan, kami menyarankannya untuk membicarakannya dengan teman baik atau keluarga. Kami sangat menyarankan setiap gadis muda untuk berbicara dengan orang tuanya atau orang dewasa lainnya yang dia percayai tentang situasinya, keputusannya dan prosedur aborsi.

    obat penggugur kandungan di apotik

    ReplyDelete
  36. WEBSITE DESIGNING COMPANY IN DELHI – Egainz.com
    We are a website designing company in Delhi help you in creating responsive websites with expert team of website designers and developers with strict timelines and affordable prices in Delhi. We have delivered more then 450 ++ Projects in India. Our team help companies, startups, individuals to design and redesigning responsive websites in India, Delhi. We have a in house team of expert web design and developers based in India, Delhi.

    ReplyDelete
  37. EduGrowUP has been conceived with the sole objective of bringing technology a step closer to life, more so in the world of education. The identity EduGrowUP in itself is a symbol of our ongoing mission. With over a decade long existence we have been consistently innovating and implementing path breaking ideas. This very objective activated us to build a platform that is available 24 X 7

    ReplyDelete
  38. Its really great being a content writer I can understand how tough is it to write and develop the content ,Thanks for sharing this wonderful informationSAP Training in Lucknow  Digital marketing training in Lucknow AUTOCAD Training in Lucknow  
      PYthon Training in Lucknow   SAP FICO Training in Lucknow  
      PHP Training in Lucknow  

    ReplyDelete
  39. Kartik Web Technology is one of the most leading IT Service provider company which is listed in Gurgaon. Gurgaon is now big IT sector where lots of famous companies are located. If you want to grow your business at higher level then you need a good website to represent your self in the Marketing. Hire us to design your company's website. We will convert your all mind imagination into reality. Give us chance to serve our services.

    website development company in Gurgaon

    ReplyDelete
  40. I Checked Your Blog & it is really one of the best Post I have ever seen... Thanks for Sharing... Keep doing it

    Android Training Institute in Delhi
    Android Training Institute in Noida

    ReplyDelete
  41. http://blog.cinu.pl/2015/11/php-static-code-analysis-vs-top-1000-wordpress-plugins.html

    ReplyDelete
  42. Software has generally been ensured under copyright law since code fits effectively into the portrayal of a scholarly work.itools virtual location crack

    ReplyDelete
  43. i am browsing this website dailly , and get nice facts from here all the time .

    ReplyDelete
  44. A backlink is a link created when one website links to another. Backlinks are important to SEO & impact for higher ranking. In my 7+ years seo Career i see, without backlinks a website doesn't rank higher on google SERP.

    Get Your 300+ High Quality DoFollow Backlinks Here!

    Order Now with Full Confidence & 100% satisfaction.

    ReplyDelete
  45. With Brandsoo, it’s never been easier or more convenient to shop high quality domain names and professional logos that’ll instantly give your brand domains for sale a leg up and resonate with your audience! With many different domain sellers all competing for your business, you need to know where your business and brand will see.

    ReplyDelete
  46. Forex Signals, MT4 and MT5 Indicators, Strategies, Expert Advisors, Forex News, Technical Analysis and Trade Updates in the FOREX IN WORLD

    Forex Signals Forex Strategies Forex Indicators Forex News Forex World

    ReplyDelete
  47. Forex Signals, MT4 and MT5 Indicators, Strategies, Expert Advisors, Forex News, Technical Analysis and Trade Updates in the FOREX IN WORLD

    Forex Signals Forex Strategies Forex Indicators Forex News Forex World

    ReplyDelete
  48. Hey! Finally we are launch 150+ High DA Dofollow Quality Backlinks here! Order Now and Boost your website ranking.

    Manual Backlinks | Quality Backlinks | Dofollow Backlinks | High Quality Backlinks

    Thank you!
    DigiPeek

    ReplyDelete
  49. Situs judi bola online UFA88 Terpercaya, juga memiliki casino online seperti, baccarat, roulette, Judi slot online, sabung ayam dan dadu online.

    ReplyDelete
  50. joker123.ratujackpot.com dan Joker123 merupakan operator Situs Judi untuk permainan mesin slot yang paling terkenal di Indonesia dimana menyediakan Link Login Joker123 secara resmi dan terpercaya serta setiap agen bisa langsung melakukan daftar Akun Slot Joker123 untuk semua member mereka. Selain menggunakan Link Altenatif juga telah tersedia Aplikasi Joker123 APK apabila ingin mendapatkan berbagai kemudahan untuk bisa mengakses dan melakukan Login Joker123 untuk bisa bermain langsung.

    ReplyDelete

  51. Whether it's a new black lace dress, some sexy lingerie, a brand new pair of shoes, in our online boutique you will find what it is Black lace dresses that you desire! Have Boutique online a look at our collection of Sequined dress fashion dresses and take advantage of our ongoing promotions and discounts! Stand out with one of our Casual dress dresses and turn heads as you walk!

    ReplyDelete
  52. Shield Security Solutions Provides Ontario Security Training, Security Guard License or Security License in Ontario. Get Started Today

    ReplyDelete
  53. indobet Situs Judi Slot Online Terlengkap 2020 Situs Judi Online populer mendukung deposit Judi Slot Online Deposit Ovo via ovo,gopay,dana, dan linkAja. Segera daftar Judi Slot Online Deposit GoPay di indobet dan klaim promo menariknya Judi Slot Online Deposit Dana.

    ReplyDelete
  54. Princess v40 for sale All about model Princess V40, brand Princess. Yacht technical specifications, layout, equipment and offers for rent and sale

    ReplyDelete
  55. University Of Rajasthan, Jaipur Revised Programming Of Examination 2021 For Uniraj BA, BSc, BCom Part Final Regular / Private / Non-College / Ex-Students
    UNIRAJ BCOM 1st Year Result
    UNIRAJ BCOM 2nd Year Result

    ReplyDelete
  56. The Key Stones behind the success to become a Salesforce Professional lies in the programming skills, analytical skills, ability to ask the right questions and interesting to learn, willingness to work hard and put in long hours and confident. Salesforce training in Chennai

    ReplyDelete
  57. I like to post such video like you post in the end of the article on tiktok and sometimes I even buy tiktok likes for them. The best site I found to get tiktok likes is https://soclikes.com/buy-tiktok-likes

    ReplyDelete