Vulnerability in WPForms Plugins Affects 6 Million WordPress Sites, Enables Payment Refund and Subscription Cancellation


### #WordPressSecurity #BugBountyProgram #VulnerabilityDisclosure

Summary: This article discusses a critical vulnerability in the WPForms plugin for WordPress that allows authenticated attackers to refund payments and cancel subscriptions. The vulnerability has been patched, and users are urged to update to the latest version to ensure their site’s security.

Threat Actor: Authenticated Attackers | authenticated attackers
Victim: WPForms Plugin | WPForms

Key Point :

  • The vulnerability allows authenticated users with subscriber-level access to refund Stripe payments and cancel subscriptions.
  • A researcher, villu164, reported the vulnerability and earned a bounty of $2,376.00 through the Wordfence Bug Bounty Program.
  • The issue was addressed in version 1.9.2.2 of the plugin, released on November 18, 2024.
  • Wordfence Premium users received immediate protection, while free users will receive it 30 days later.
  • Users are strongly encouraged to update their WPForms plugin to the latest version to mitigate risks.

💥 Time to wrap up this year and kick-off the new year with a bang! We’re wrapping up the year with our End of Year Holiday ExtravaganzaHigh-Risk Bonus Blitz Challenge, and Superhero Challenge for the Wordfence Bug Bounty Program. Through January 6th, 2025:

  • All in-scope vulnerability types for WordPress plugins/themes with >= 1,000 active installations are in-scope for ALL researchers
  • All plugins and themes with 50-999 active installs hosted in the WordPress.org repository and updated within the last 2 years are in-scope for all researchers!
  • All plugins and themes hosted in the WordPress.org repository with any install count are in scope for our preset list of high threat vulnerabilities.
  • $150 bonus awarded when a researcher submits at least 15 valid high threat vulnerabilities, and then a $50 bonus awarded for every 5 submitted thereafter.
  • Minimum bounty of $5 for all valid in-scope submissions.
  • All researchers earn automatic bonuses of between 5% to 180% for valid submissions
  • Pending report limits are increased for all
  • It’s possible to earn up to $31,200 for high impact vulnerabilities!

On October 23th, 2024, we received a submission for a Missing Authorization to Payment Refund and Subscription Cancellation vulnerability in WPForms, a WordPress plugin with more than 6,000,000 active installations. This vulnerability makes it possible for an authenticated attacker, with subscriber-level access and above, to refund Stripe payments and cancel Stripe subscriptions.

Props to villu164 who discovered and responsibly reported this vulnerability through the Wordfence Bug Bounty Program. This researcher earned a bounty of $2,376.00 for this discovery. Our mission is to Secure the Web, which is why we are investing in quality vulnerability research and collaborating with researchers of this caliber through our Bug Bounty Program. We are committed to making the WordPress ecosystem more secure, which ultimately makes the entire web more secure.

We’d also like to say a special congratulations to villu164, who became our first researcher to earn the WordPress Superhero badge through the Wordfence Bug Bounty Program!

Wordfence Premium, Wordfence Care, and Wordfence Response users received a firewall rule to protect against any exploits targeting this vulnerability on November 15, 2024. Sites using the free version of Wordfence will receive the same protection 30 days later on December 15, 2024.

We sent the full disclosure details to the Awesome Motive team on November 14, 2024, and received a response on the next day. The developer released a patch on November 18, 2024. We would like to commend the Awesome Motive team for their prompt response and timely patch.

We urge users to update their sites with the latest patched version of WPForms, version 1.9.2.2 at the time of this writing, as soon as possible.

Vulnerability Summary from Wordfence Intelligence

The WPForms plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the ‘wpforms_is_admin_page’ function in versions starting from 1.8.4 up to, and including, 1.9.2.1. This makes it possible for authenticated attackers, with Subscriber-level access and above, to refund payments and cancel subscriptions.

Technical Analysis

WPForms is the most popular WordPress form builder plugin, allowing users to create various types of forms, such as contact forms, feedback forms, subscription forms, and payment forms, utilizing an easy-to-use drag-and-drop builder.

Examining the code reveals that the plugin uses the ajax_single_payment_refund() and ajax_single_payment_cancel() functions in the SingleActionsHandler class to handle the Stripe payment actions.

private function hooks() {

    if ( wpforms_is_admin_ajax() ) {
        add_action( 'wp_ajax_wpforms_stripe_payments_refund', [ $this, 'ajax_single_payment_refund' ] );

The wpforms_is_admin_ajax() function is used to determine if the request is an admin AJAX request. This function does not perform any authorization.

function wpforms_is_admin_ajax(): bool {

	if ( ! wpforms_is_ajax() ) {
		return false;
	}

	$ref = wp_get_raw_referer();

	if ( ! $ref ) {
		return false;
	}

	$path       = wp_parse_url( $ref, PHP_URL_PATH );
	$admin_path = wp_parse_url( admin_url(), PHP_URL_PATH );

	// Is an admin AJAX call if HTTP referer contain an admin path.
	return strpos( $path, $admin_path ) !== false;
}

Although the ajax_single_payment_refund() and ajax_single_payment_cancel() AJAX functions are nonce protected, the nonce can unfortunately be obtained by authenticated attackers in the vulnerable version. Also, there are no capability checks in the functions.

public function ajax_single_payment_refund() {

    if ( ! isset( $_POST['payment_id'] ) ) {
        wp_send_json_error( [ 'message' => esc_html__( 'Missing payment ID.', 'wpforms-lite' ) ] );
    }

    $this->check_payment_collection_type();
    check_ajax_referer( 'wpforms-admin', 'nonce' );

    $payment_id = (int) $_POST['payment_id'];
    $payment_db = wpforms()->obj( 'payment' )->get( $payment_id );

    if ( empty( $payment_db ) ) {
        wp_send_json_error( [ 'message' => esc_html__( 'Payment not found in the database.', 'wpforms-lite' ) ] );
    }

    $args = [
        'metadata' => [
            'refunded_by' => 'wpforms_dashboard',
        ],
        'reason'   => 'requested_by_customer',
    ];

    $refund = $this->payment_intents->refund_payment( $payment_db->transaction_id, $args );
public function ajax_single_payment_cancel() {

    if ( ! isset( $_POST['payment_id'] ) ) {
        wp_send_json_error( [ 'message' => esc_html__( 'Payment ID not provided.', 'wpforms-lite' ) ] );
    }

    $this->check_payment_collection_type();
    check_ajax_referer( 'wpforms-admin', 'nonce' );

    $payment_id = (int) $_POST['payment_id'];
    $payment_db = wpforms()->obj( 'payment' )->get( $payment_id );

    if ( empty( $payment_db ) ) {
        wp_send_json_error( [ 'message' => esc_html__( 'Subscription not found in the database.', 'wpforms-lite' ) ] );
    }

    $cancel = $this->payment_intents->cancel_subscription( $payment_db->subscription_id );

While this is a simple vulnerability, this issue makes it possible for authenticated attackers to invoke these AJAX actions and refund Stripe payments or cancel Stripe subscriptions. This can lead to a loss of revenue on sites using WPForms to manage subscriptions.

Disclosure Timeline

November 8, 2024 – We received the submission for the Missing Authorization to Authenticated (Subscriber+) Payment Refund and Subscription Cancellation vulnerability in WPForms via the Wordfence Bug Bounty Program.
November 14, 2024 – We validated the report and confirmed the proof-of-concept exploit.
November 14, 2024 – We sent over the full disclosure details to the vendor. The vendor acknowledged the report and began working on a fix.
November 15, 2024Wordfence Premium, Care, and Response users received a firewall rule to provide protection against any exploits that may target this vulnerability.
November 18, 2024 – The fully patched version of the plugin, 1.9.2.2, was released.
December 15, 2024 – Wordfence Free users will receive the same protection.

Conclusion

In this blog post, we detailed a Missing Authorization to Payment Refund and Subscription Cancellation vulnerability within the WPForms plugin affecting versions 1.8.4 through 1.9.2.1. This vulnerability allows authenticated threat actors with subscriber-level permissions or higher to refund Stripe payments and cancel Stripe subscriptions. The vulnerability has been addressed in version 1.9.2.2 of the plugin.

We encourage WordPress users to verify that their sites are updated to the latest patched version of WPForms as soon as possible considering the critical nature of this vulnerability.

Wordfence Premium, Wordfence Care, and Wordfence Response users received a firewall rule to protect against any exploits targeting this vulnerability on November 15, 2024. Sites using the free version of Wordfence will receive the same protection 30 days later on December 15, 2024.

If you know someone who uses this plugin on their site, we recommend sharing this advisory with them to ensure their site remains secure, as this vulnerability poses a significant risk.

Source: https://www.wordfence.com/blog/2024/12/6000000-wordpress-sites-protected-against-payment-refund-and-subscription-cancellation-vulnerability-in-wpforms-wordpress-plugin