CVE-2026-68900 Overview
CVE-2026-68900 is a stored cross-site scripting (XSS) vulnerability in Wekan, an open source kanban board built with Meteor. The flaw affects versions from 8.72 up to but not including 10.23. The addBoardHTMLToZip() function in client/lib/exportHTML.js reads card titles and bodies through textContent, which decodes HTML entities, and then interpolates those values into content.innerHTML in the exported index.html. A board member can plant an entity-encoded event-handler payload in a card title that remains inert on the live board but executes when a recipient opens the downloaded HTML export and clicks the card [CWE-79].
Critical Impact
A malicious board member can exfiltrate all board data contained in an HTML export, including content added after their membership was revoked.
Affected Products
- Wekan versions 8.72 through 10.22
- HTML board export functionality (client/lib/exportHTML.js)
- Meteor-based Wekan deployments serving multi-user boards
Discovery Timeline
- 2026-08-19 - CVE-2026-68900 published to NVD
- 2026-08-19 - Last updated in NVD database
- Version 10.23 - Wekan releases patched version resolving the issue
Technical Details for CVE-2026-68900
Vulnerability Analysis
The vulnerability is a stored XSS triggered by a second HTML parse during export. Wekan lets board members enter card titles and bodies as plain text. When the export routine runs, it reads those values through the DOM textContent property, which decodes any HTML entities the attacker stored. The decoded string is then concatenated into an HTML template and assigned to content.innerHTML inside the exported index.html. The recipient's browser parses the attacker-controlled markup as live HTML when they click the card modal.
Because the exported file runs in the recipient's file:// or hosting origin, the injected script can read the entire DOM of the export. That includes board content added after the attacker was removed from the board, since the export snapshot is generated with the current permissions of whoever runs it.
Root Cause
The root cause is a double-decode pattern. The attacker stores an entity-encoded payload such as <img src=x onerror=...> in a card title. On the live board, Wekan renders this as inert text. During export, textContent decodes the entities back into raw markup, producing the literal string <img src=x onerror=...>. That string is then interpolated into content.innerHTML, which parses and executes it. The sink is innerHTML assignment on untrusted data whose entity encoding has already been stripped.
Attack Vector
Exploitation requires the attacker to have board-member privileges to store the payload, and a victim who downloads and opens the HTML export and clicks the crafted card. The payload runs in the recipient's browser context and can read and transmit all data present in the export bundle.
// Get all text content from the card
const allText = this.textContent.trim();
- // Show modal with card details
- modal.innerHTML = '<button style="position:absolute;top:10px;right:10px;padding:5px 10px;background:#f0f0f0;border:1px solid #ccc;border-radius:4px;cursor:pointer;">Close</button>';
- modal.querySelector('button').onclick = () => { modal.style.display = 'none'; document.body.style.overflow = 'auto'; };
+ // Show modal with card details. Build it with DOM nodes and assign
+ // the card title/body through textContent — NEVER innerHTML. Those
+ // values come from .textContent, which DECODES HTML entities, so a
+ // card title holding entity-encoded markup (e.g.
+ // "<img src=x onerror=...>") decodes to a live tag; assigning it
+ // to innerHTML would re-parse and execute it — a stored XSS that fires
+ // when a recipient clicks the card in the exported HTML
+ // (GHSA-8r5p-4q9j-f5jx). textContent inserts them as inert text.
+ while (modal.firstChild) { modal.removeChild(modal.firstChild); }
+
+ const closeBtn = document.createElement('button');
+ closeBtn.textContent = 'Close';
+ closeBtn.onclick = () => { modal.style.display = 'none'; document.body.style.overflow = 'auto'; };
+ modal.appendChild(closeBtn);
const content = document.createElement('div');
- content.innerHTML = '<h2 style="margin-bottom:10px;">' + titleText + '</h2>...' + allText + '...';
+ const titleEl = document.createElement('h2');
+ titleEl.textContent = titleText;
+ content.appendChild(titleEl);
Source: GitHub Wekan Commit 2d32e34. The patch replaces innerHTML assignment with DOM node construction and textContent writes.
Detection Methods for CVE-2026-68900
Indicators of Compromise
- Card titles or bodies containing entity-encoded HTML tokens such as <script, <img, <svg, or event-handler attributes like onerror=, onclick=, or onload=.
- Outbound HTTP requests from exported Wekan HTML files to unexpected external hosts, especially requests carrying board content in query strings or POST bodies.
- Wekan HTML exports (index.html) containing decoded <script> or event-handler tags inside data- attributes or card sections.
Detection Strategies
- Scan the Wekan MongoDB cards collection for entity-encoded HTML in title and description fields using patterns like <\s*(script|img|svg|iframe).
- Statically inspect generated export bundles before distribution and reject any file where card DOM nodes contain scriptable child elements.
- Monitor browser telemetry from workstations opening exported Wekan HTML files for script execution on file:// origins loading Wekan-branded pages.
Monitoring Recommendations
- Enable audit logging for card-edit events and alert on titles containing HTML entities that decode to tags.
- Track board-member add and remove events, and correlate them with the presence of suspicious card titles authored by removed users.
- Log all board-export actions with the exporting user, board ID, and destination, so post-incident triage can identify who received a poisoned export.
How to Mitigate CVE-2026-68900
Immediate Actions Required
- Upgrade Wekan to version 10.23 or later, which builds the export modal with DOM nodes and assigns untrusted values through textContent.
- Audit existing card titles and descriptions for entity-encoded HTML and neutralize any payloads before generating new exports.
- Revoke and reissue any HTML exports created between versions 8.72 and 10.22 that were shared with external recipients.
Patch Information
The fix is delivered in Wekan v10.23. The patch rewrites the card-modal construction in client/lib/exportHTML.js to build DOM nodes with document.createElement() and assign card title and body values via textContent, eliminating the innerHTML sink. See the GitHub Security Advisory GHSA-8r5p-4q9j-f5jx and the Wekan v10.23 release notes.
Workarounds
- Disable the HTML board export feature until the upgrade is applied, and offer JSON or CSV exports instead.
- Restrict board membership to trusted users and require review of card content before boards are exported.
- Open exported HTML files only in a sandboxed browser profile with JavaScript disabled until all boards are verified to be free of encoded payloads.
# Verify installed Wekan version and upgrade via Docker
docker inspect wekan --format '{{.Config.Image}}'
docker pull quay.io/wekan/wekan:v10.23
docker stop wekan && docker rm wekan
docker run -d --name wekan --restart=always \
-p 8080:8080 \
--env-file /opt/wekan/wekan.env \
quay.io/wekan/wekan:v10.23
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

