CVE-2025-69316

TableOn <= 1.0.4.2 - Reflected Cross-Site Scripting

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.1
CVSS Score
6.1
CVSS Score
medium
Severity
1.0.4.3
Patched in
8d
Time to patch

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

Technical Details

Affected versions<=1.0.4.2
PublishedJanuary 20, 2026
Last updatedJanuary 27, 2026
Affected pluginposts-table-filterable
Research Plan
Unverified

# 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 like orderby.
  • 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)

  1. A user visits a page containing the [tableon] shortcode.
  2. The plugin's shortcode handler (likely in a class handling the frontend display) parses the request.
  3. The handler checks for filter parameters in the $_GET or $_REQUEST arrays to maintain the state of the search UI.
  4. The parameter (e.g., tableon_txt_search) is assigned to a variable used in the HTML template for the search input field.
  5. Sink: The value is echoed directly into the value attribute of an <input> tag or within a <script> block for AJAX initialization without being passed through esc_attr() or wp_json_encode().
    • Example Vulnerable Code: echo '<input type="text" name="tableon_txt_search" value="' . $_GET['tableon_txt_search'] . '">';

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_nonce or tableon_ajax_nonce (inferred).
  • JS Variable: Check for window.tableon_vars or window.tableon_data (inferred).
  • Acquisition Method:
    1. Navigate to the page containing the [tableon] shortcode.
    2. Use browser_eval to extract the nonce: browser_eval("window.tableon_vars?.nonce").

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

  1. 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
  2. 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

  1. Search Source Code: After the request, verify the exact location of the reflection in the response.
  2. Verify via Browser: Use browser_navigate to the URL and check if the alert was triggered.
  3. Check for Escaping: Confirm that characters like " and < are NOT converted to &quot; or &lt;.

9. Alternative Approaches

If tableon_txt_search is not the vulnerable parameter, try the following:

  1. Pagination Parameter: ?tableon_page=1<script>alert(1)</script>
  2. Sorting Parameter: ?orderby=title<script>alert(1)</script>
  3. 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_table with the malicious parameter in the body/URL and check the JSON response for unescaped reflection.
Research Findings
Static analysis — not yet PoC-verified

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

--- a/classes/tableon.php
+++ b/classes/tableon.php
@@ -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.