Stored XSS vulnerability in WordPress Download Plugins and Themes from Dashboard plugin.

The WordPress Download Plugins and Themes from Dashboard plugin, which has 10,000+ active installations, was prone to an unauthenticated stored XSS vulnerability in version 1.5.0 and below.

Reference

CVE-2019-17239

Unauthenticated stored XSS

In the “includes/settings/class-alg-download-plugins-settings.php”, the plugin registers the save_settings function via the admin_init hook than can be triggered by any user, authenticated or not:

add_action( 'admin_init',      array( $this, 'save_settings' ) );
...
...
function save_settings() {
   if ( isset( $_POST[ $this-> id . '_save_settings' ] ) || isset( $_POST[ $this-> id . '_reset_settings' ] ) ) {
     foreach ( $this-> get_settings() as $field ) {
        $field_id    = $this-> id . '_' . $field['id'];
        $field_value = null;
        if ( isset( $_POST[ $this-> id . '_save_settings' ] ) && isset( $_POST[ $field_id ] ) ) {
          $field_value = $_POST[ $field_id ];
        } elseif ( isset( $_POST[ $this-> id . '_reset_settings' ] ) && isset( $field['default'] ) ) {
           $field_value = $field['default'];
        }
        if ( 'plugins_bulk_period' === $field['id'] || 'themes_bulk_period' === $field['id'] ) {
           $prev_value = get_option( $field_id, '' );
        }
        if ( null !== $field_value ) {
           update_option( $field_id, stripslashes( $field_value ) );
        }
        if ( 'plugins_bulk_period' === $field['id'] && $field_value != $prev_value ) {
           alg_download_plugins()-> core-> cron_unschedule_plugins_event();
           alg_download_plugins()-> core-> cron_schedule_plugins_event();
        }
        if ( 'themes_bulk_period' === $field['id'] && $field_value != $prev_value ) {
           alg_download_plugins()-> core-> cron_unschedule_themes_event();
           alg_download_plugins()-> core-> cron_schedule_themes_event();
        }
     }
     add_action( 'admin_notices', array( $this, 'admin_notice__success' ) );
  }
}

The function, used to save the plugin settings, is accessible to anyone because it does not check for capability and does not use a security nonce. Some of the saved settings are neither validated nor sanitized:

  • alg_download_plugins_dashboard_temp_dir
  • alg_download_plugins_dashboard_plugins_bulk_dir
  • alg_download_plugins_dashboard_themes_bulk_dir
  • alg_download_plugins_dashboard_plugins_single_zip_file_name
  • alg_download_plugins_dashboard_themes_single_zip_file_name

An unauthenticated user can inject JavaScript or any HTML code into one of the above fields in order to target administrators when they visit the plugin’s settings page:

Timeline

The vulnerability was reported to the wordpress.org team on September 26, 2019, and a new version 1.6.0 was released on September 30.

Recommendations

Update as soon as possible if you have version 1.5.0 or below installed.
If you are using our web application firewall for WordPress, NinjaFirewall WP Edition (free) and NinjaFirewall WP+ Edition (premium), you are protected against this vulnerability.

Stay informed about the latest vulnerabilities in WordPress plugins and themes: @nintechnet