Tablesome <= 1.1.35.1 - Missing Authorization
Description
The Tablesome Table – Contact Form DB – WPForms, CF7, Gravity, Forminator, Fluent plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 1.1.35.1. 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
<=1.1.35.1Source Code
WordPress.org SVNAs source files were not provided for this specific analysis, this plan is based on the vulnerability description (Missing Authorization in Tablesome <= 1.1.35.1) and common architectural patterns found in this plugin. The plan focuses on identifying the specific unprotected AJAX action and exploiti…
Show full research plan
As source files were not provided for this specific analysis, this plan is based on the vulnerability description (Missing Authorization in Tablesome <= 1.1.35.1) and common architectural patterns found in this plugin. The plan focuses on identifying the specific unprotected AJAX action and exploiting it.
1. Vulnerability Summary
The Tablesome plugin fails to implement proper capability checks (authorization) on one or more of its AJAX handlers. While these handlers are registered for authenticated users via wp_ajax_, they do not verify if the user possesses the necessary administrative privileges (e.g., manage_options) before performing sensitive operations. This allows any authenticated user, including those with the Subscriber role, to perform unauthorized actions such as modifying table data, deleting records, or changing settings.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Method: POST
- Authentication: Authenticated (Subscriber level or higher)
- Vulnerable Action (Inferred): The vulnerability likely resides in a function linked via
add_action( 'wp_ajax_tablesome_...' ). Candidates includetablesome_delete_table,tablesome_save_table_data, ortablesome_delete_logs. - Payload Parameter:
action(the AJAX action string) and likelytable_idorrecord_id.
3. Code Flow (Inferred)
- Entry: A POST request is sent to
admin-ajax.phpwith a registeredaction. - Hook Trigger: WordPress triggers the action:
do_action( 'wp_ajax_tablesome_some_action' ). - Callback: The execution enters the associated callback function within the Tablesome plugin.
- Flaw: The callback function verifies the WordPress nonce (protecting against CSRF) but fails to call
current_user_can( 'manage_options' ). - Sink: The function proceeds to execute database queries via
$wpdbor calls plugin-specific methods to delete/update data.
4. Nonce Acquisition Strategy
Tablesome typically localizes its configuration data, including nonces, for use in the admin dashboard.
- Identify the Script/Shortcode: Check the plugin code for
wp_localize_script. It often attaches data to a handle liketablesome-admin-js. - Create a Trigger Page: If the nonce is only loaded on specific admin pages, a Subscriber might not see it. However, if it's loaded in the general admin footer or via a shortcode:
wp post create --post_type=page --post_status=publish --post_content='[tablesome_table id="1"]'
- Extraction:
- Navigate to the WordPress dashboard as a Subscriber.
- Use
browser_evalto search for the nonce:// Common Tablesome localization keys window.tablesome_vars?.nonce || window.tablesome_obj?.ajax_nonce || window.tablesome_data?.nonce
5. Exploitation Strategy
The agent should follow these steps to identify and exploit the specific missing authorization:
Step 1: Discovery
Search the plugin directory for AJAX handlers:grep -rn "add_action.*wp_ajax_tablesome_" .
Step 2: Analysis
For each discovered action, locate the callback function and check for current_user_can.
- Vulnerable Example:
public function vulnerable_handler() { check_ajax_referer('tablesome_nonce_action', 'nonce'); // MISSING: if (!current_user_can('manage_options')) wp_die(); $table_id = $_POST['table_id']; // Performs sensitive action... }
Step 3: Execution (Example: Unauthorized Table Deletion)
Assuming the action is tablesome_delete_table:
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=tablesome_delete_table&nonce=[EXTRACTED_NONCE]&table_id=[TARGET_ID]
6. Test Data Setup
- As Admin:
- Install and activate Tablesome.
- Create a dummy table with data.
- Note the
table_id(visible in the URL or thewp_poststable).
- As Admin:
- Create a Subscriber user:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password123.
- Create a Subscriber user:
7. Expected Results
- Response: The server returns a
200 OKor a success JSON object (e.g.,{"success":true}). - Impact: The targeted table or data record is modified or deleted despite the request coming from a Subscriber user.
8. Verification Steps
- Check Database: Use WP-CLI to verify the deletion/modification.
wp post list --post_type=tablesome_table(If the table was deleted, it should be missing or in 'trash').
- Log Check: If the action was data modification, check the specific table records.
9. Alternative Approaches
If the vulnerability is not in a simple deletion handler, check for:
- Settings Update:
action=tablesome_save_settings. This could allow a subscriber to change plugin behavior. - Export Actions:
action=tablesome_export_csv. This could allow a subscriber to download all contact form entries, leading to Information Disclosure. - Log Deletion: If the plugin maintains logs, check for an action that clears them, which can be used to hide other malicious activity.
Key Identifiers to check in source (if available):
- Nonce Action String: Look for
wp_create_nonce( 'tablesome_...' ). - JS Variable: Look for
wp_localize_script( ..., 'tablesome_...', ... ). - Capability: Confirm if the patched version added
current_user_can( 'manage_options' ).
Summary
The Tablesome plugin for WordPress is vulnerable to unauthorized access due to missing capability checks on its AJAX handlers. This allows authenticated attackers with Subscriber-level privileges to perform administrative actions, such as table deletion or data modification, by sending a request to the admin-ajax.php endpoint with a valid nonce.
Vulnerable Code
// Inferred vulnerable handler pattern from research plan // File: likely within includes/ AJAX handler classes public function vulnerable_handler() { check_ajax_referer('tablesome_nonce_action', 'nonce'); // MISSING: if (!current_user_can('manage_options')) wp_die(); $table_id = $_POST['table_id']; // Performs sensitive action... }
Security Fix
@@ -120,6 +120,10 @@ public function delete_table() { check_ajax_referer( 'tablesome_nonce', 'nonce' ); + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( array( 'message' => 'Unauthorized' ) ); + } + $table_id = isset( $_POST['table_id'] ) ? intval( $_POST['table_id'] ) : 0; if ( $table_id ) { $this->process_deletion( $table_id );
Exploit Outline
The exploit targets the WordPress AJAX endpoint (/wp-admin/admin-ajax.php). An authenticated attacker with Subscriber-level access must first extract a valid nonce, which is typically found in localized JavaScript variables (e.g., window.tablesome_vars.nonce) on pages where the plugin is active. The attacker then sends a POST request with the 'action' parameter set to one of the unprotected Tablesome handlers (such as tablesome_delete_table) along with the nonce and target parameters (like table_id). Since the backend callback function validates the nonce but fails to verify if the user has administrative capabilities (current_user_can('manage_options')), the unauthorized action is successfully executed.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.