Multiple vulnerabilities fixed in WordPress GiveWP plugin.

The WordPress GiveWP plugin, which has 70,000+ active installations, fixed vulnerabilities affecting version 2.5.9 and below.

Reference

A CVE ID has been requested and we’ll update this post when it is assigned.

Unauthenticated settings change

In the “includes/gateways/stripe/includes/admin/admin-actions.php” script, the give_stripe_connect_save_options function is loaded via the admin_init hook:

function give_stripe_connect_save_options() {

   $get_vars = give_clean( $_GET );

   // If we don't have values here, bounce.
   if (
      ! isset( $get_vars['stripe_publishable_key'] )
      || ! isset( $get_vars['stripe_user_id'] )
      || ! isset( $get_vars['stripe_access_token'] )
      || ! isset( $get_vars['stripe_access_token_test'] )
      || ! isset( $get_vars['connected'] )
   ) {
      return false;
   }

   // Update keys.
   give_update_option( 'give_stripe_connected', $get_vars['connected'] );
   give_update_option( 'give_stripe_user_id', $get_vars['stripe_user_id'] );
   give_update_option( 'live_secret_key', $get_vars['stripe_access_token'] );
   give_update_option( 'test_secret_key', $get_vars['stripe_access_token_test'] );
   give_update_option( 'live_publishable_key', $get_vars['stripe_publishable_key'] );
   give_update_option( 'test_publishable_key', $get_vars['stripe_publishable_key_test'] );

   // Delete option for user API key.
   give_delete_option( 'stripe_user_api_keys' );

}
add_action( 'admin_init', 'give_stripe_connect_save_options' );

The function lacks a capability check and a security nonce. Because the admin_init hook can be triggered by anyone, an unauthenticated user can tamper with the authentication credentials of the Stripe Connect payment gateway: ACCESS_TOKEN, REFRESH_TOKEN, PUBLISHABLE_KEY, ACCOUNT_ID.

Authenticated settings change

In the “includes/admin/emails/ajax-handler.php” script, the give_set_notification_status_handler function is loaded via the wp_ajax hook. It is used to enable or disable email notifications sent by GiveWP to the administrator:

function give_set_notification_status_handler() {
   $notification_id = isset( $_POST['notification_id'] ) ? give_clean( $_POST['notification_id'] ) : '';
   if ( ! empty( $notification_id ) && give_update_option( "{$notification_id}_notification", give_clean( $_POST['status'] ) ) ) {
      wp_send_json_success();
   }

   wp_send_json_error();
}

add_action( 'wp_ajax_give_set_notification_status', 'give_set_notification_status_handler' );

The function lacks a capability check and a security nonce and thus can be accessed by an authenticated user such as a subscriber.

This vulnerability could be used in conjunction with the previous one: after tampering with the payment gateway, the attacker could disable all email notifications sent to the admin, which includes the notification sent when a new donation is received.

Additional issues

In the “includes/misc-functions.php” script, the give_get_ip function is used to retrieve the user IP address:

function give_get_ip() {

   $ip = '127.0.0.1';

   if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
      // check ip from share internet
      $ip = $_SERVER['HTTP_CLIENT_IP'];
   } elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
      // to check ip is pass from proxy
      $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
   } elseif ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) {
      $ip = $_SERVER['REMOTE_ADDR'];
   }

   /**
    * Filter the IP
    *
    * @since 1.0
    */
   $ip = apply_filters( 'give_get_ip', $ip );

   // Filter empty values.
   if ( false !== strpos( $ip, ',' ) ) {
      $ip = give_clean( explode( ',', $ip ) );
      $ip = array_filter( $ip );
      $ip = implode( ',', $ip );
   } else {
      $ip = give_clean( $ip );
   }

   return $ip;
}

It relies on untrusted user input (HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR) that is sanitised in order to prevent attacks such as XSS, but isn’t properly validated: GiveWP will accept Client-IP: foo as a valid IP address.

Timeline

The vulnerability was reported to the authors on October 18, 2019 and a new version 2.5.10 was released on October 28, 2019.

Recommendations

Update as soon as possible if you have version 2.5.9 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