Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-55085

CVE-2026-55085: Etherpad Cross-Site Scripting Vulnerability

CVE-2026-55085 is a cross-site scripting flaw in Etherpad that allows attackers to execute malicious scripts when users open a crafted pad. This post covers technical details, affected versions, and mitigation steps.

Updated:

CVE-2026-55085 Overview

Etherpad, a widely deployed real-time collaborative editor, contains a stored cross-site scripting (XSS) vulnerability in versions prior to 3.3.1. The flaw resides in result.appendSpan within src/static/js/domline.ts, which interpolates the start attribute of a numbered list directly into an unquoted <ol start=...> attribute before assigning the markup to node.innerHTML. Any user with write access to a pad can inject markup that executes JavaScript when other users, including administrators, open the pad or view /timeslider.

Critical Impact

Attackers with pad write access can achieve stored XSS against every subsequent viewer, including administrators, enabling session hijacking and account takeover.

Affected Products

  • Etherpad versions prior to 3.3.1
  • Etherpad instances accepting .etherpad imports from untrusted users
  • Etherpad deployments exposing /timeslider to shared pad viewers

Discovery Timeline

  • 2026-08-19 - CVE-2026-55085 published to NVD
  • 2026-08-19 - Last updated in NVD database

Technical Details for CVE-2026-55085

Vulnerability Analysis

The vulnerability is a stored cross-site scripting flaw classified under [CWE-79]. Etherpad's rendering pipeline builds an ordered list element by concatenating the start attribute value directly into an HTML string. The resulting markup is then assigned to node.innerHTML, causing the browser to parse any attacker-supplied content as live HTML.

Because the start value flows from the pad's attribute pool, an attacker who can write to a pad can persist a payload that breaks out of the <ol> tag. The payload triggers when any user, including an administrator, opens the pad or views the /timeslider history endpoint.

Root Cause

The root cause is missing output encoding and missing type coercion on a numeric HTML attribute. The start attribute of an <ol> element must be an integer, but the code accepted arbitrary strings from the attribute pool. ImportEtherpad.setPadRaw in src/node/utils/ImportEtherpad.ts also accepts attacker-controlled attribute-pool values from a crafted .etherpad import, including list:number1 entries with malicious start values, extending the attack surface to import functionality.

Attack Vector

An attacker with pad write access, or one who can convince an administrator to import a crafted .etherpad file, stores a numbered list attribute containing a payload such as 1><svg/onload=...>. When the pad is subsequently rendered, the unquoted attribute closes the <ol> tag and executes the injected markup in the victim's session context.

typescript
            postHtml = `</li></ul>${postHtml}`;
          } else {
            if (start) { // is it a start of a list with more than one item in?
-              if (Number.parseInt(start[1]) === 1) { // if its the first one at this level?
+              // The `start` value comes verbatim from the attribute pool (which
+              // an attacker can populate via a crafted `.etherpad` import), so it
+              // must never be interpolated raw into the markup. An <ol> start is
+              // only ever an integer: coerce it and HTML-escape it defensively so
+              // a value such as `1><svg/onload=...>` cannot break out of the tag.
+              const startNum = Number.parseInt(start[1]);
+              if (startNum === 1) { // if its the first one at this level?
                // Add start class to DIV node
                lineClass = `${lineClass} ` + `list-start-${listType}`;
              }
+              const startAttr = Number.isNaN(startNum)
+                ? ''
+                : ` start="${Security.escapeHTMLAttribute(String(startNum))}"`;
              preHtml +=
-                `<ol start=${start[1]} class="list-${Security.escapeHTMLAttribute(listType)}"><li>`;
+                `<ol${startAttr} class="list-${Security.escapeHTMLAttribute(listType)}"><li>`;
            } else {
              // Handles pasted contents into existing lists
              preHtml += `<ol class="list-${Security.escapeHTMLAttribute(listType)}"><li>`;

Source: GitHub Etherpad Commit d828185. The patch coerces start to an integer, escapes it as an HTML attribute, and quotes the attribute value.

Detection Methods for CVE-2026-55085

Indicators of Compromise

  • Pad content or .etherpad import files containing list:number attribute values with non-numeric characters such as <, >, or quote marks in the start field.
  • Unexpected outbound requests from browsers loading pad URLs or /timeslider endpoints, indicating payload beaconing.
  • Etherpad server logs showing .etherpad imports from unprivileged accounts followed by administrator pad views.

Detection Strategies

  • Inspect stored pad attribute pools for list:number entries where the numeric portion contains characters outside [0-9].
  • Deploy a Content Security Policy (CSP) in report-only mode to surface inline script violations originating from pad rendering.
  • Review web proxy and browser telemetry for anomalous script execution on pages served by the Etherpad application.

Monitoring Recommendations

  • Alert on Etherpad instances running versions below 3.3.1 via software inventory scans.
  • Monitor .etherpad import events and correlate them with subsequent administrator pad access.
  • Log and review pad edits by newly created or low-trust accounts for injection patterns.

How to Mitigate CVE-2026-55085

Immediate Actions Required

  • Upgrade Etherpad to version 3.3.1 or later on all instances.
  • Audit existing pads and stored .etherpad files for malicious list:number attribute values and purge affected content.
  • Restrict pad write access and .etherpad import capabilities to trusted users until patching is complete.

Patch Information

The fix is available in Etherpad 3.3.1. See the GitHub Security Advisory GHSA-f7h5-v9hm-548j, the pull request #7937, and the v3.3.1 release notes. The patch integer-coerces the start value, applies Security.escapeHTMLAttribute, and quotes the attribute in the emitted markup.

Workarounds

  • Disable .etherpad file imports at the reverse proxy or application layer until the upgrade is applied.
  • Enforce a strict Content Security Policy that blocks inline scripts and unsafe event handlers on pad and timeslider routes.
  • Limit pad write permissions to authenticated, trusted users and prohibit anonymous editing.
bash
# Upgrade Etherpad to the fixed release
git fetch --tags
git checkout v3.3.1
pnpm install --frozen-lockfile
pnpm run build
systemctl restart etherpad

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.