SECURITY ADVISORY / 01

CVE-2024-4845 Exploit & Vulnerability Analysis

Complete CVE-2024-4845 security advisory with proof of concept (PoC), exploit details, and patch analysis for email-subscribers.

email-subscribers products NVD ↗
Exploit PoC Vulnerability Patch Analysis

The Exploit

An authenticated attacker with Subscriber-level access or higher can inject arbitrary SQL through the options[list_id] parameter in Icegram Express forms.

POST /wp-admin/admin-ajax.php HTTP/1.1
Host: target.local
Content-Type: application/x-www-form-urlencoded
Cookie: wordpress_logged_in=<subscriber_session>

action=ig_es_get_subscriber_lists&options[list_id]=1 UNION SELECT user_login,user_pass,user_email FROM wp_users--

The attacker receives a response that leaks the WordPress user table, including password hashes. Because the plugin fails to type-cast the list_id parameter before embedding it into a SQL WHERE clause, any SQL syntax in the parameter is executed as part of the same query. A UNION SELECT stacked query reveals sensitive data; a DELETE payload destroys records.

What the Patch Did

Before

if ( is_array( $list_ids ) ) {
	$list_ids_str = implode( ',', $list_ids );
} else {
	$list_ids_str = $list_ids;
}

$where = "id IN ({$list_ids_str})";

After

if ( is_array( $list_ids ) ) {
	$list_ids = array_map( 'intval', $list_ids );
	$list_ids_str = implode( ',', $list_ids );
} else {
	$list_id = intval( $list_ids );
	$list_ids_str = $list_id;
}

$where = "id IN ({$list_ids_str})";

The patch applies intval() to the $list_ids parameter before interpolation. intval() is PHP's integer-casting function; it parses the input as a decimal integer and strips all non-numeric characters. This ensures that only numeric values—not SQL syntax—reach the query string. The fix is applied conditionally: array elements are cast via array_map(), and scalar values are cast directly. No parameterized query ($wpdb->prepare()) is used, but explicit type conversion achieves the same defense by narrowing the input alphabet to only digits.

Root Cause

CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')

The vulnerability originates in the options[list_id] request parameter, parsed by the AJAX handler ig_es_get_subscriber_lists. This value is passed to the ES_DB_Lists class method (implied by the file path) without sanitization. The dataflow is linear: request parameter → local variable $list_ids → string interpolation into $where → SQL IN clause. The trust boundary is crossed at the interpolation step: the plugin assumes $list_ids contains only numeric list IDs, but it does not validate or escape this assumption. An attacker with Subscriber access (the minimum role required to trigger AJAX endpoints in WordPress) can inject SQL keywords (UNION, SELECT, --) that alter the query structure.

Why It Works

The load-bearing line is intval( $list_ids ). Remove it, and the bug remains: an attacker can still pass 1 UNION SELECT ... as list_id, and the string will be embedded directly into the WHERE clause. intval() is the sole defense: it converts the string to an integer, truncating any appended SQL syntax. The other lines—the is_array() check and array_map()—are defense-in-depth: they handle the case where the caller provides an array of IDs (common in WordPress for bulk operations). If only a scalar were supported, a single intval() would suffice. The array_map() ensures that every element in an array is cast before the array is imploded, preventing an attacker from injecting SQL via any element of a multi-value parameter like options[list_id][0], options[list_id][1], etc.

Hardening Checklist

  • Use parameterized queries ($wpdb->prepare()) for all user-controlled values in SQL. Example: $wpdb->prepare( "SELECT * FROM {$wpdb->posts} WHERE ID IN (%d)", $id ) for scalar values, or build the placeholder string dynamically for arrays. This is the WordPress-native, industry-standard defense and is simpler than manual type casting.

  • Cast numeric IDs to intval() or absint() at the trust boundary (request handler) before passing to business logic. Do not assume the business layer will do it. absint() is preferred in WordPress when negative values are nonsensical.

  • Audit all implode() calls on user-controlled arrays. They are a common vector for this bug: implode() does not escape or type-cast its input. Search the codebase for patterns like implode( ',', $var ) where $var originates from $_GET, $_POST, or options[] parameters.

  • Use static analysis to flag unparameterized $wpdb queries. Tools like PHPStan with WordPress-specific rule sets will catch direct string interpolation into $wpdb->query(), $wpdb->get_results(), etc. Integrate into CI/CD.

  • Require code review for any SQL construction, especially in database abstraction layers. The ES_DB_Lists class is a data layer; SQL construction at this level is high-risk because it affects many callers. Enforce a policy that all database code be reviewed by a second engineer before merge.

References

  • https://nvd.nist.gov/vuln/detail/CVE-2024-4845

Frequently asked questions about CVE-2024-4845

What is CVE-2024-4845?

CVE-2024-4845 is a security vulnerability identified in email-subscribers. This security advisory provides detailed technical analysis of the vulnerability, exploit methodology, affected versions, and complete remediation guidance.

Is there a PoC (proof of concept) for CVE-2024-4845?

Yes. This writeup includes proof-of-concept details and a technical exploit breakdown for CVE-2024-4845. Review the analysis sections above for the PoC walkthrough and code examples.

How does CVE-2024-4845 get exploited?

The technical analysis section explains the vulnerability mechanics, attack vectors, and exploitation methodology affecting email-subscribers. PatchLeaks publishes this information for defensive and educational purposes.

What products and versions are affected by CVE-2024-4845?

CVE-2024-4845 affects email-subscribers. Check the affected-versions section of this advisory for specific version ranges, vulnerable configurations, and compatibility information.

How do I fix or patch CVE-2024-4845?

The patch analysis section provides guidance on updating to patched versions, applying workarounds, and implementing compensating controls for email-subscribers.

What is the CVSS score for CVE-2024-4845?

The severity rating and CVSS scoring for CVE-2024-4845 affecting email-subscribers is documented in the vulnerability details section. Refer to the NVD entry for the current authoritative score.