CVE-2025-68542

Checkout Gateway for IRIS <= 1.3 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
1.4
Patched in
5d
Time to patch

Description

The Checkout Gateway for IRIS plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 1.3. This makes it possible for unauthenticated attackers to perform an unauthorized action.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.3
PublishedFebruary 5, 2026
Last updatedFebruary 9, 2026
Affected plugincheckout-gateway-iris

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the methodology for analyzing and exploiting **CVE-2025-68542**, a missing authorization vulnerability in the **Checkout Gateway for IRIS** plugin. --- ### 1. Vulnerability Summary The **Checkout Gateway for IRIS** plugin (<= 1.3) fails to implement proper capability ch…

Show full research plan

This research plan outlines the methodology for analyzing and exploiting CVE-2025-68542, a missing authorization vulnerability in the Checkout Gateway for IRIS plugin.


1. Vulnerability Summary

The Checkout Gateway for IRIS plugin (<= 1.3) fails to implement proper capability checks on a function that performs sensitive actions. In WordPress, functions hooked to admin_init or registered as AJAX actions (wp_ajax_) without an explicit current_user_can() check are accessible to any user who can reach those execution paths. Because admin_init runs even on admin-ajax.php and admin-post.php requests (including those from unauthenticated users), this leads to a Missing Authorization vulnerability.

2. Attack Vector Analysis

  • Target Endpoint: wp-admin/admin-ajax.php or wp-admin/admin-post.php (likely) or any front-end request if hooked to init.
  • Vulnerable Action: Likely a settings-update function or a gateway configuration handler.
  • Authentication Level: Unauthenticated (Public).
  • Parameters: Likely POST parameters corresponding to gateway settings (e.g., iris_merchant_id, iris_terminal_id, iris_api_key).
  • Preconditions: The plugin must be active.

3. Code Flow (Inferred)

  1. Entry Point: An unauthenticated user sends a POST request to /wp-admin/admin-post.php or /wp-admin/admin-ajax.php.
  2. Hook Registration: The plugin registers a function via add_action( 'admin_init', '...' ) or add_action( 'wp_ajax_nopriv_...', '...' ).
  3. Missing Check: The callback function (e.g., save_iris_settings) processes $_POST data and calls update_option() without verifying current_user_can( 'manage_options' ).
  4. Sink: update_option('checkout_gateway_iris_settings', ...) is called, overwriting plugin configuration.

4. Nonce Acquisition Strategy

If the vulnerability exists in a function hooked to admin_init intended for settings saving, it may or may not check for a nonce.

  • Scenario A: Missing Nonce: No nonce is required. The exploit is a direct POST request.
  • Scenario B: Exposed Nonce: If the plugin uses wp_create_nonce('iris_settings_action'), we must find where it is leaked.
    1. Search the codebase for wp_localize_script.
    2. Check if the plugin enqueues scripts on the login page or frontend.
    3. If a shortcode exists (check grep -r "add_shortcode" .), create a page with that shortcode:
      wp post create --post_type=page --post_status=publish --post_content='[iris_checkout]'
    4. Navigate to the page and use browser_eval to extract the nonce:
      browser_eval("window.iris_params?.nonce") (Variable names are inferred).

5. Exploitation Strategy

Step 1: Identification

Search the plugin source for the vulnerable sink:

grep -rn "update_option" .
grep -rn "admin_init" .
grep -rn "wp_ajax_nopriv" .

Look for a function that handles $_POST data without a current_user_can call.

Step 2: Crafting the Payload

If a settings-save function is found, identify the option name and parameter names.
Example (Inferred):

  • Action: save_iris_config
  • Parameters: merchant_id=ATTACKER_ID&api_key=MALICIOUS_KEY

Step 3: Execution (HTTP Request)

Using the http_request tool, send the unauthorized update:

{
  "method": "POST",
  "url": "http://localhost:8080/wp-admin/admin-post.php",
  "headers": {
    "Content-Type": "application/x-www-form-urlencoded"
  },
  "body": "action=iris_save_settings&merchant_id=999999&terminal_id=888888&nonce_field=NONCE_VALUE_IF_NEEDED"
}

6. Test Data Setup

  1. Install/Activate: Ensure checkout-gateway-iris version 1.3 is installed.
  2. Initial State: Configure the gateway with "legitimate" values using WP-CLI:
    wp option update checkout_iris_settings '{"merchant_id":"12345", "terminal_id":"54321"}'
  3. Shortcode Page (If needed):
    wp post create --post_type=page --post_title="Payment" --post_status=publish --post_content="[iris_payment_form]"

7. Expected Results

  • The server responds with a 302 redirect (common for admin-post.php) or a 200 OK.
  • The unauthenticated request successfully triggers the update_option call.
  • The plugin configuration is altered to the attacker-supplied values.

8. Verification Steps

After sending the HTTP request, verify the change via WP-CLI:

# Check the specific option used by the plugin
wp option get checkout_iris_settings

If the output reflects 999999 (the attacker value), the exploitation is confirmed.

9. Alternative Approaches

  • REST API: If the plugin registers REST routes, check register_rest_route for a permission_callback that returns true or is missing.
  • Direct Option Overwrite: If the admin_init hook is even more generic (e.g., using a variable option name from $_POST['option_name']), this could escalate to a full site takeover by overwriting users_can_register or default_role.
  • Missing Nonce in AJAX: If wp_ajax_nopriv_ is used, try the request with no nonce at all, as many developers omit them for "public" AJAX actions.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Checkout Gateway for IRIS plugin for WordPress is vulnerable to unauthorized settings modification due to a missing capability check in a function hooked to admin_init. This allows unauthenticated attackers to overwrite sensitive payment gateway configurations, such as Merchant IDs and API keys, by sending a crafted request to common WordPress admin endpoints.

Vulnerable Code

// checkout-gateway-iris.php

add_action('admin_init', 'iris_save_settings_callback');

function iris_save_settings_callback() {
    if (isset($_POST['iris_submit_settings'])) {
        // Missing current_user_can('manage_options') or similar check
        // Missing nonce verification (check_admin_referer)
        
        $settings = array(
            'merchant_id' => sanitize_text_field($_POST['iris_merchant_id']),
            'terminal_id' => sanitize_text_field($_POST['iris_terminal_id']),
            'api_key'     => sanitize_text_field($_POST['iris_api_key'])
        );

        update_option('checkout_gateway_iris_settings', $settings);
    }
}

Security Fix

--- a/checkout-gateway-iris.php
+++ b/checkout-gateway-iris.php
@@ -10,6 +10,11 @@
 function iris_save_settings_callback() {
     if (isset($_POST['iris_submit_settings'])) {
+
+        if (!current_user_can('manage_options')) {
+            wp_die(__('Unauthorized access'));
+        }
+
+        check_admin_referer('iris_save_action', 'iris_nonce');
+
         $settings = array(
             'merchant_id' => sanitize_text_field($_POST['iris_merchant_id']),

Exploit Outline

The exploit targets the WordPress admin_init hook, which executes even for unauthenticated users accessing /wp-admin/admin-post.php. 1. Target Endpoint: Send a POST request to http://victim-site.com/wp-admin/admin-post.php. 2. Payload: Include the parameter that triggers the plugin's settings update logic (e.g., iris_submit_settings=1) along with attacker-controlled values for gateway configuration (e.g., iris_merchant_id=attacker_account). 3. Authentication: No authentication is required because the plugin fails to verify user capabilities (current_user_can) or validate a security nonce (check_admin_referer) before processing the POST data. 4. Verification: After the request, the plugin's configuration in the wp_options table will reflect the attacker's values, potentially redirecting payments to the attacker's account.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.