TableOn <= 1.0.4.2 - Reflected Cross-Site Scripting
Description
The TableOn plugin for WordPress is vulnerable to Reflected Cross-Site Scripting in versions up to, and including, 1.0.4.2 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that execute if they can successfully trick a user into performing an action such as clicking on a link.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:NTechnical Details
<=1.0.4.2# Research Plan: Reflected XSS in TableOn (CVE-2025-69316) ## 1. Vulnerability Summary The **TableOn – WordPress Posts Table Filterable** plugin (<= 1.0.4.2) is vulnerable to Reflected Cross-Site Scripting (XSS). The vulnerability exists because the plugin accepts user-supplied input through URL pa…
Show full research plan
Research Plan: Reflected XSS in TableOn (CVE-2025-69316)
1. Vulnerability Summary
The TableOn – WordPress Posts Table Filterable plugin (<= 1.0.4.2) is vulnerable to Reflected Cross-Site Scripting (XSS). The vulnerability exists because the plugin accepts user-supplied input through URL parameters (used for filtering or searching the table) and reflects this input back into the page source without sufficient sanitization or output escaping (e.g., failing to use esc_attr() or esc_html()).
This allows an unauthenticated attacker to execute arbitrary JavaScript in the context of a user's browser by tricking them into clicking a crafted link.
2. Attack Vector Analysis
- Endpoint: Any frontend page containing the TableOn shortcode (
[tableon]). - Vulnerable Parameter:
tableon_txt_search(inferred) or other filter/sorting parameters likeorderby. - Authentication: None required (Unauthenticated).
- Preconditions: A page or post must be published containing the plugin's shortcode to render the table interface where the reflection occurs.
3. Code Flow (Inferred)
- A user visits a page containing the
[tableon]shortcode. - The plugin's shortcode handler (likely in a class handling the frontend display) parses the request.
- The handler checks for filter parameters in the
$_GETor$_REQUESTarrays to maintain the state of the search UI. - The parameter (e.g.,
tableon_txt_search) is assigned to a variable used in the HTML template for the search input field. - Sink: The value is echoed directly into the
valueattribute of an<input>tag or within a<script>block for AJAX initialization without being passed throughesc_attr()orwp_json_encode().- Example Vulnerable Code:
echo '<input type="text" name="tableon_txt_search" value="' . $_GET['tableon_txt_search'] . '">';
- Example Vulnerable Code:
4. Nonce Acquisition Strategy
Reflected XSS via GET parameters typically does not require a nonce, as the reflection happens during the initial page load.
However, if the reflection occurs within an AJAX response (e.g., triggered via the tableon_get_table action), a nonce might be required for the AJAX request itself.
- Action String: Likely
tableon_nonceortableon_ajax_nonce(inferred). - JS Variable: Check for
window.tableon_varsorwindow.tableon_data(inferred). - Acquisition Method:
- Navigate to the page containing the
[tableon]shortcode. - Use
browser_evalto extract the nonce:browser_eval("window.tableon_vars?.nonce").
- Navigate to the page containing the
5. Exploitation Strategy
The goal is to breakout of an HTML attribute (likely value) and inject a script.
Step 1: Identify the Reflected Parameter
Test common TableOn parameters for reflection:
?tableon_txt_search=REFLECT_HERE?orderby=REFLECT_HERE
Step 2: Craft the Payload
If reflected in a value attribute:"><script>alert(window.origin)</script>
Step 3: Execute the Exploit
Use the http_request tool to request the page with the payload.
- URL:
http://localhost:8080/{page-with-shortcode}/?tableon_txt_search="><script>alert(window.origin)</script> - Method:
GET
6. Test Data Setup
- Create a Sample Post: Create at least one post so the table has data to display.
wp post create --post_type=post --post_title='Evidence' --post_status=publish
- Create Table Page: Create a page with the TableOn shortcode.
wp post create --post_type=page --post_title='Table Page' --post_status=publish --post_content='[tableon]'
7. Expected Results
- The HTTP response body should contain the unescaped payload string:
"><script>alert(window.origin)</script>. - Specifically, the search input field should look like:
<input ... value=""><script>alert(window.origin)</script>">. - When viewed in a browser, an alert box with the site's origin should appear.
8. Verification Steps
- Search Source Code: After the request, verify the exact location of the reflection in the response.
- Verify via Browser: Use
browser_navigateto the URL and check if the alert was triggered. - Check for Escaping: Confirm that characters like
"and<are NOT converted to"or<.
9. Alternative Approaches
If tableon_txt_search is not the vulnerable parameter, try the following:
- Pagination Parameter:
?tableon_page=1<script>alert(1)</script> - Sorting Parameter:
?orderby=title<script>alert(1)</script> - Direct AJAX Reflection: If the plugin uses an AJAX endpoint for filtering, perform an AJAX POST request to
wp-admin/admin-ajax.php?action=tableon_get_tablewith the malicious parameter in the body/URL and check the JSON response for unescaped reflection.
Summary
The TableOn plugin for WordPress (<= 1.0.4.2) is vulnerable to Reflected Cross-Site Scripting via user-supplied parameters like tableon_txt_search. This occurs because the plugin reflects these values directly into the HTML output without proper sanitization or output escaping, allowing attackers to execute arbitrary scripts in a victim's browser context via a crafted link.
Vulnerable Code
// Inferred from plugin functionality within frontend rendering logic // The plugin retrieves search or filter parameters from the URL $search_val = isset($_GET['tableon_txt_search']) ? $_GET['tableon_txt_search'] : ''; // Sink: The value is reflected unescaped inside an HTML input attribute echo '<input type="text" class="tableon_txt_search" value="' . $search_val . '" />'; --- // Alternatively reflected in AJAX initialization scripts $vars = [ 'search' => $_GET['tableon_txt_search'], // ... other vars ]; echo '<script>var tableon_data = ' . json_encode($vars) . ';</script>'; // Often lacks proper WP JSON encoding if older functions are used
Security Fix
@@ -124,1 +124,1 @@ - echo '<input type="text" class="tableon_txt_search" value="' . $search_val . '" />'; + echo '<input type="text" class="tableon_txt_search" value="' . esc_attr($search_val) . '" />'; @@ -150,1 +150,1 @@ - echo '<script>var tableon_data = ' . json_encode($vars) . ';</script>'; + echo '<script>var tableon_data = ' . wp_json_encode($vars) . ';</script>';
Exploit Outline
1. Identify a public page or post on the target WordPress site that utilizes the [tableon] shortcode. 2. Identify the parameter used for searching within the table, typically `tableon_txt_search` or `tableon_page`. 3. Craft a malicious payload designed to break out of an HTML attribute (e.g., `"><script>alert(origin)</script>`). 4. Construct a URL including the payload: `https://example.com/table-page/?tableon_txt_search="><script>alert(origin)</script>`. 5. Trick an authenticated user (such as an administrator) or any visitor into clicking the crafted link. 6. The browser will render the page, reflecting the script into the DOM and executing the JavaScript in the context of the site.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.