Joli Table Of Contents is a WordPress plugin that automatically builds a table of contents for posts and pages, used on around 7,000 active sites. During security testing a stored Cross-Site Scripting flaw was found and assigned CVE-2025-15694: the plugin does not sanitize and escape some of its settings before printing them back on its own admin page. A high-privilege user (Administrator) can store JavaScript in the headings_overflow setting that then executes on the plugin’s settings screen — including in setups where administrators are not allowed to post raw HTML, such as WordPress Multisite. The issue affects versions 2.0.0 – 2.8.0 and is fixed in 2.8.1.
| CVE | CVE-2025-15694 |
| Joli Table Of Contents 2.0.0 – 2.8.0 | |
| All Time | 145 580 |
| Active installations | 7 000+ |
| Publicly Published | September 3, 2026 |
| Last Updated | September 3, 2026 |
| Researcher | Krugov Artyom |
| OWASP TOP-10 | A03:2021 – Injection (Cross-Site Scripting) |
| CWE | CWE-79 |
| PoC | Yes |
| Exploit | No |
| Reference | https://www.cve.org/CVERecord?id=CVE-2025-15694 https://wpscan.com/vulnerability/9ebaf1aa-eb8b-4c62-bbd0-07918503fbf1/ |
| Plugin Security Certification by CleanTalk | ![]() |
| Logo of the plugin |
PSC by CleantalkJoin the community of developers who prioritize security. Highlight your plugin in the WordPress catalog.
Timeline
| August 22, 2025 | Plugin testing and vulnerability detection in the Joli Table Of Contents have been completed |
| August 22, 2025 | I contacted the author of the plugin and provided a vulnerability PoC with a description and recommendations for fixing |
| August 13, 2026 | The vendor released the patched version 2.8.1 |
| September 3, 2026 | Registered CVE-2025-15694 |
Discovery of the Vulnerability
While auditing the settings handling of the Joli Table Of Contents plugin, I found that several options saved from the plugin’s General settings tab are stored and later printed back into the admin page without proper output escaping. One of them is the headings_overflow option, submitted as the joli_table_of_contents_settings[headings_overflow] parameter. The value is written straight into an HTML attribute on the settings form, so a payload that closes the attribute injects executable markup that is stored in the database and runs every time the settings page is opened — a persistent (Stored) XSS. Because the sink is the plugin’s own admin screen, the payload fires in the browser of any administrator who visits that page.
Understanding of Stored XSS attacks
Stored (persistent) Cross-Site Scripting saves the attacker’s payload on the server so it is served automatically to whoever opens the affected page. This case requires an Administrator account, which is why the CVSS score is Low on a standard single site — an administrator there can already post raw HTML through the unfiltered_html capability. The risk becomes real on WordPress Multisite and hardened installations, where site administrators do not hold unfiltered_html: the missing escaping lets them bypass that restriction and store JavaScript that runs in the context of the network, and it also widens the blast radius of a single compromised admin session or a CSRF-style trick against an administrator.
Exploiting the Stored XSS Vulnerability
To reproduce the vulnerability on an affected version (2.0.0 – 2.8.0):
- Log in as an Administrator and open the Joli TOC plugin tab.
- Go to the General settings section.
- Insert the XSS payload into the
joli_table_of_contents_settings[headings_overflow]parameter (the Headings overflow field) and save the settings. - Reopen the settings page and move the mouse over the field to trigger the payload.
PoC payload placed in the headings_overflow setting:
123123"onmouseover='alert(777)'
After saving, the value is reflected into the settings form and the injected onmouseover handler executes alert(777) in the admin context. In a real attack the harmless alert() would be replaced with code that creates a rogue network administrator, plants a backdoor, or exfiltrates session data — running silently whenever the plugin settings page is loaded.
Recommendations for Improved Security
To mitigate CVE-2025-15694:
- Update Joli Table Of Contents to version 2.8.1 or later immediately.
- Sanitize settings on input and escape them on output with
esc_attr()/esc_html()so option values can never break out of their HTML context. - Do not rely on the administrator role as a trust boundary for HTML — escape output even for high-privilege users, especially on Multisite where
unfiltered_htmlis disallowed. - Add CSRF nonces to settings forms so options cannot be changed by a forged request against a logged-in administrator.
- Implement a strong Content Security Policy (CSP) to block inline JavaScript execution.
- Deploy a Web Application Firewall to filter XSS payloads before they reach the application.
To prevent this type of attack, follow our methods of XSS prevention.
By addressing Stored XSS vulnerabilities like CVE-2025-15694 early, WordPress site owners and plugin developers can protect administrators and entire networks from account takeover. Stay vigilant, stay secure.
#WordPressSecurity #StoredXSS #JoliTOC #WebsiteSafety #StayProtected
Use CleanTalk solutions to improve the security of your website
Krugov Artyom
