CVE-2026-24524

Tablesome <= 1.2.8 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.2.9
Patched in
106d
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.2.8
PublishedJanuary 26, 2026
Last updatedMay 11, 2026
Affected plugintablesome

Source Code

WordPress.org SVN
Patched

Patched version not available.

Research Plan
Unverified

# 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_table
    • nonce: A valid AJAX nonce (e.g., tablesome_table_nonce)
    • table_id: ID of a table to modify
    • table_data: JSON or serialized payload representing table configuration
  • Preconditions: The attacker must be logged in as a Subscriber.

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers AJAX actions in the constructor of a class like Tablesome_AJAX or Tablesome_Tables_Admin.
    • add_action( 'wp_ajax_tablesome_save_table', array( $this, 'save_table' ) );
  2. Hook Execution: When a Subscriber sends a request to admin-ajax.php?action=tablesome_save_table, WordPress triggers the callback.
  3. 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(); }
  4. Action Performance: The function proceeds to update the database (e.g., update_post_meta or a custom table update) based on the table_data provided 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.

  1. Identify the Script: Look for where Tablesome localizes data. In typical versions, it uses wp_localize_script for tablesome-admin or tablesome-common.
  2. Locate the Nonce: Check for localized objects such as tablesome_vars, tablesome_admin_data, or tablesome_table_data.
  3. 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_navigate to view this page as the Subscriber user.
    • Extract: Use browser_eval to find the nonce:
      browser_eval("window.tablesome_vars?.nonce || window.tablesome_admin_data?.nonce")
    • Verification: If the nonce action is -1 or a generic string, it may be obtainable from various contexts.

5. Exploitation Strategy

The goal is to modify an existing table's title or configuration as a Subscriber.

  1. Discovery:
    • Use ls -R to 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.
  2. Target Selection: Focus on tablesome_save_table or tablesome_update_settings.
  3. 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
      
  4. Execute: Use the http_request tool with the Subscriber's session cookies.

6. Test Data Setup

  1. Create Admin User: To set up the initial table.
  2. Create Subscriber User: To perform the exploit.
  3. 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
  4. Determine Table ID: Note the ID of the created post (e.g., ID 123).

7. Expected Results

  • Successful Response: The server returns a 200 OK response, 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

  1. 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).
  2. Check Capability: Verify the user is still a Subscriber:
    • wp user get [USER_ID] --field=roles

9. Alternative Approaches

  • Settings Modification: If tablesome_save_table is not vulnerable, look for tablesome_save_settings. This could allow changing plugin-wide options.
  • Record Deletion: Look for tablesome_delete_record or tablesome_delete_table.
    • Body: action=tablesome_delete_table&nonce=[NONCE]&id=[TABLE_ID]
  • Payload Variation: Some AJAX handlers expect JSON-encoded data in a specific parameter (e.g., payload=...). Check the PHP source for json_decode($_POST['...']).
Research Findings
Static analysis — not yet PoC-verified

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

--- a/wp-content/plugins/tablesome/includes/admin/class-tablesome-ajax.php
+++ b/wp-content/plugins/tablesome/includes/admin/class-tablesome-ajax.php
@@ -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.