CVE-2025-68881

AppExperts <= 1.4.5 - Authenticated (Subscriber+) SQL Injection

mediumImproper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
6.5
CVSS Score
6.5
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The AppExperts plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 1.4.5 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for authenticated attackers, with subscriber-level access and above, to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.4.5
PublishedJanuary 22, 2026
Last updatedJanuary 27, 2026
Affected pluginappexperts
Research Plan
Unverified

This research plan outlines the steps to identify and exploit CVE-2025-68881, an authenticated SQL injection vulnerability in the **AppExperts** plugin (version <= 1.4.5). ### 1. Vulnerability Summary The **AppExperts** plugin fails to properly sanitize and prepare SQL queries when processing user-…

Show full research plan

This research plan outlines the steps to identify and exploit CVE-2025-68881, an authenticated SQL injection vulnerability in the AppExperts plugin (version <= 1.4.5).

1. Vulnerability Summary

The AppExperts plugin fails to properly sanitize and prepare SQL queries when processing user-supplied input via AJAX or REST API endpoints accessible to Subscriber-level users. Specifically, a parameter is concatenated into a $wpdb query without using the $wpdb->prepare() method or proper integer casting/escaping. This allows an authenticated attacker to inject arbitrary SQL commands, potentially leading to sensitive data extraction (e.g., user hashes, site configuration).

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php (or potentially a REST route under /wp-json/ae/v1/)
  • Action: Likely an AJAX action registered with wp_ajax_ (e.g., ae_get_data, ae_get_settings, or ae_search_products).
  • Vulnerable Parameter: (Inferred) id, category_id, post_id, or order_by.
  • Authentication: Subscriber level (PR:L).
  • Preconditions: The attacker must be logged in as a Subscriber and obtain a valid AJAX nonce if the handler enforces one.

3. Code Flow (Discovery Phase)

To locate the exact sink, the agent must perform the following trace:

  1. Identify AJAX Handlers:
    grep -rn "wp_ajax_" wp-content/plugins/appexperts/ --include="*.php"
    
  2. Filter for Subscriber-Accessible Actions:
    Look for actions that do not have explicit current_user_can('manage_options') checks within their callback functions.
  3. Trace Database Sinks:
    Search for $wpdb methods used with variable interpolation rather than preparation:
    grep -rP '\$wpdb->(get_results|get_row|get_var|query)\s*\(\s*".*\$' wp-content/plugins/appexperts/
    
  4. Pinpoint the Vulnerability:
    Identify where a $_POST, $_GET, or $_REQUEST variable is used in the query identified in Step 3.
    • Target File (Likely): includes/class-ae-ajax.php or public/class-appexperts-public.php.
    • Target Function: Any function registered to a wp_ajax_ hook that performs a lookup by ID or filter.

4. Nonce Acquisition Strategy

If the AJAX handler uses check_ajax_referer or wp_verify_nonce, the nonce must be extracted from the frontend.

  1. Identify Localization:
    Search for wp_localize_script to find the JavaScript object name containing the nonce:
    grep -rn "wp_localize_script" wp-content/plugins/appexperts/
    
    • Expected Variable: ae_ajax_object or appexperts_data (inferred).
  2. Create Trigger Content:
    If the script only loads on specific pages (e.g., a "Mobile App Config" page or via a shortcode), identify the shortcode:
    grep -rn "add_shortcode" wp-content/plugins/appexperts/
    
    Create a page with that shortcode:
    wp post create --post_type=page --post_status=publish --post_content='[ae_app_config]' --post_title='Exploit Trigger'
    
  3. Extract via Browser:
    Use browser_navigate to the created page and browser_eval to extract the nonce:
    // Example (replace with real identifiers found in Step 1)
    window.ae_ajax_object?.nonce || window.appexperts_data?.ajax_nonce
    

5. Exploitation Strategy

Once the action, parameter, and nonce are identified, perform a Time-Based Blind SQL injection to confirm.

  • Step 1: Test for Injection (Time-based)
    Send an HTTP request via the http_request tool.

    • Method: POST
    • URL: http://localhost:8080/wp-admin/admin-ajax.php
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body:
      action=[VULNERABLE_ACTION]&security=[NONCE]&[PARAM]=1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)
      
    • Confirmation: A response delay of ~5 seconds confirms the vulnerability.
  • Step 2: Data Extraction (Boolean or Union)
    If the response reflects query results, use UNION-based extraction. If not, use Boolean-based checks against the wp_users table:

    • Payload (to check if admin username starts with 'a'):
      1 AND (SELECT 1 FROM wp_users WHERE user_login LIKE 'a%' AND ID=1)
      

6. Test Data Setup

  1. Create Subscriber User:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password
    
  2. Plugin Configuration: Ensure the plugin is activated and any necessary "App" or "Configuration" is created so the vulnerable query has a baseline record to run against.
    # (Example if a custom table needs data)
    wp db query "INSERT INTO wp_ae_apps (name) VALUES ('Test App')" 
    

7. Expected Results

  • Vulnerability Confirmation: The http_request tool reports a latency significantly higher than the baseline when the SLEEP() payload is sent.
  • Data Leakage: In a UNION-based scenario, the response body contains the user_pass hash or auth_key from the database.

8. Verification Steps

After the HTTP exploit, verify the database state to ensure no corruption occurred and to confirm the data retrieved:

  1. Match Hash:
    wp db query "SELECT user_pass FROM wp_users WHERE ID = 1"
    
    Compare this result with the data extracted via the SQL injection.

9. Alternative Approaches

  • Error-Based SQLi: If WP_DEBUG is on or the plugin echoes $wpdb->last_error, use updatexml() or extractvalue() for faster extraction.
  • REST API: If no AJAX handler is found, check for REST routes in includes/class-ae-rest-api.php registered via register_rest_route. Look for parameters in the args array that lack a validate_callback or sanitize_callback using absint.
  • Order By Injection: If the injection is in an ORDER BY clause, use (CASE WHEN (1=1) THEN ID ELSE name END).
Research Findings
Static analysis — not yet PoC-verified

Summary

The AppExperts plugin for WordPress (up to version 1.4.5) contains an authenticated SQL injection vulnerability due to the failure to sanitize user-supplied parameters and the lack of query preparation using $wpdb->prepare(). This allows attackers with Subscriber-level access to append arbitrary SQL commands to existing queries and extract sensitive information from the site's database.

Exploit Outline

To exploit this vulnerability, an attacker first authenticates as a Subscriber-level user and identifies a vulnerable AJAX action (e.g., via wp-admin/admin-ajax.php) or REST API endpoint that processes database lookups. If a nonce is required, it can be extracted from the frontend by visiting a page where the plugin's scripts are localized. The attacker then sends a crafted POST request containing a malicious payload in a parameter used in a SQL query (such as an ID or filter). By using a time-based blind SQL injection payload (e.g., 'AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)'), the attacker can confirm the vulnerability based on response latency and subsequently use similar techniques to leak data like user password hashes.

Check if your site is affected.

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