If you run a Discourse forum—say for your club, your company, or a large online community—you likely use, or have seen, the DiscoTOC plugin. DiscoTOC is a theme component that makes navigating long discussions easier by automatically generating a clickable Table of Contents (TOC) based on post headings.
But in 2022, an issue was discovered—CVE-2022-39270—that could allow certain users to inject arbitrary HTML into your site. This, in the wrong hands, could lead to XSS (cross-site scripting) or worse.
This post breaks down what happened, how the vulnerability worked, how to fix it, and how you can check if your Discourse site is safe. We’ll give code snippets, links for reference, and step-by-step solutions—all in plain American English.
What Is CVE-2022-39270?
CVE-2022-39270 refers to a vulnerability in the DiscoTOC Discourse theme component. DiscoTOC reads through your posts’ headings to build a live Table of Contents. However, before the fix, it would allow users with permissions to create topics in a TOC-enabled category to include specially crafted input that results in arbitrary HTML injection. This means someone could add code to the page from just a topic post!
Who Is Affected?
- Anyone running a Discourse forum with the DiscoTOC plugin/theme component enabled.
- Only users with permission to create topics in TOC-enabled categories (and who have the required "trust level" as set in DiscoTOC settings).
- Exploit possible only when DiscoTOC is enabled on the category/topic.
How Did the Exploit Work?
The exploit happened because DiscoTOC did not properly sanitize heading content before inserting it into the DOM as HTML. Here's an example.
Suppose a user posts this in a new topic
DiscoTOC would read both H3 headings and generate a Table of Contents entry for each. But, without sanitization, the <img> tag (which is *not* valid Markdown for a heading) would be interpreted, and the inline onerror handler would trigger JavaScript.
After posting this, opening the topic (with TOC on) would pop the "DiscoTOC XSS" alert—a classic sign of an XSS attack.
Technical Background: The Flawed Code
Before the fix, inside assets/javascripts/discotoc.js.es6 (or similar), the code responsible for building the TOC might have done something like:
// BAD: Inserts heading.innerHTML directly as HTML!
tocElement.innerHTML += <li>${heading.innerHTML}</li>;
This template literal lets *any* HTML in the heading text through—dangerous if the input isn’t sanitized.
HTML Injection: Insert custom HTML, including scripts, into the page.
- XSS (Cross-site scripting): Run JavaScript in the browser of any user viewing the topic, potentially stealing cookies, session info, or acting on behalf of the user.
The Fix
Developers fixed the issue on the main branch. The official commit with the fix is available for review.
Key part of the fix: They switched to *sanitizing* the heading text before inserting it into the Table of Contents.
Pseudo-code for the fixed logic might look like
// GOOD: Insert escaped textContent, NOT raw HTML!
tocElement.innerHTML += <li>${heading.textContent}</li>;
Click Check for Updates and apply any available updates!
If you can’t update right away, disable the theme component until you can.
Link to official fix instructions:
- DiscoTOC GitHub Security Advisory
- CVE Record
Final Notes: Protect Your Forum
This vulnerability shows how even helpful, non-core components can put your community at risk if not maintained. Always:
Stay alert to security advisories.
Stay safe, keep your Discourse users happy, and don’t give attackers an easy win!
Links/References
1. DiscoTOC Official Repo
2. DiscoTOC Security Advisory
3. CVE-2022-39270 (NVD database)
4. Discourse Official Site
Have questions or need help patching? Drop a reply below or DM!
Timeline
Published on: 10/06/2022 18:16:00 UTC
Last modified on: 10/11/2022 05:15:00 UTC