CVE-2026-55086
Etherpad: Import/export use Math.random() for temp file paths; predictable paths on shared /tmp enable symlink-based file overwrite
Etherpad is a real-time collaborative editor. Prior to 3.1.0, src/node/handler/ImportHandler.ts and src/node/handler/ExportHandler.ts derive temporary filenames from Math.random() and place them in os.tmpdir(). On a host with a shared world-writable temporary directory, a local unprivileged attacker who predicts a filename can precreate a symbolic link to a file writable by the Etherpad process. Subsequent import or export operations can follow the link through fs.writeFile, fs.rename, or document-conversion output and overwrite the target with partially attacker-controlled content. This issue is fixed in version 3.1.0.
Attack profile
How easy it is to exploit
- Attack vector
- Local
- Complexity
- High
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- Low
- Integrity
- Low
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
4.2
Etherpad: Import/export use Math.random() for temp file paths; predictable paths on shared /tmp enable symlink-based file overwrite
Etherpad is a real-time collaborative editor. Prior to 3.1.0, src/node/handler/ImportHandler.ts and src/node/handler/ExportHandler.ts derive temporary filenames from Math.random() and place them in os.tmpdir(). On a host with a shared world-writable temporary directory, a local unprivileged attacker who predicts a filename can precreate a symbolic link to a file writable by the Etherpad process. Subsequent import or export operations can follow the link through fs.writeFile, fs.rename, or document-conversion output and overwrite the target with partially attacker-controlled content. This issue is fixed in version 3.1.0.
- Record
CVE-2026-55086- CVSS 3.1
- 4.2 Medium
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:N - Weakness
- CWE-59, CWE-377
- Updated
- 2026-11-02
EUVDEUVD-2026-62741
4.2
Etherpad is a real-time collaborative editor. Prior to 3.1.0, src/node/handler/ImportHandler.ts and src/node/handler/ExportHandler.ts derive temporary filenames from Math.random() and place them in os.tmpdir(). On a host with a shared world-writable temporary directory, a local unprivileged attacker who predicts a filename can precreate a symbolic link to a file writable by the Etherpad process. Subsequent import or export operations can follow the link through fs.writeFile, fs.rename, or document-conversion output and overwrite the target with partially attacker-controlled content. This issue is fixed in version 3.1.0.
- Record
EUVD-2026-62741- CVSS 3.1
- 4.2 Medium
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-2jwf-f4xq-f24h
4.2
ep_etherpad-lite: Import/export uses Math.random() for temp file paths; predictable paths on shared /tmp enable symlink-based file overwrite
Description
src/node/handler/ImportHandler.ts and src/node/handler/ExportHandler.ts both compute their temporary working-file paths as:
const randNum = Math.floor(Math.random() * 0xFFFFFFFF);
const srcFile = `${os.tmpdir()}/etherpad_export_${randNum}.html`;
const destFile = `${os.tmpdir()}/etherpad_export_${randNum}.${type}`;
Two flaws compound:
-
Math.random()is not crypto-secure. It yields at most ~32 bits of entropy and is predictable across calls within the same Node process (V8 shares PRNG state between consecutiveMath.random()invocations). An attacker on the same host who observes any earlier temp-file name from logs or other side channels can predict subsequent names. -
The paths land in
os.tmpdir(). On a typical Linux system this is/tmp— a shared world-writable directory. An unprivileged local attacker can pre-create a symbolic link at a predicted path pointing at any file the Etherpad process can write:ln -s /etc/etherpad/SESSIONKEY.txt /tmp/etherpad_export_<predicted>.htmlWhen
ExportHandlercallsfs.writeFile(srcFile, html)(orImportHandlercallsfs.rename(srcFile, destFile)/sofficewrites its converted output to the path), the open syscall follows the symlink and either reads from or overwrites the linked target. For deployments where the Etherpad process runs as a privileged user (notably some Docker base images that run as root, snap confinement edge cases, or hand-rolled systemd units), this becomes arbitrary file overwrite.
The Import path is more impactful in practice: the file content the attacker can land in the symlink target is partially attacker-controlled (the post-soffice/post-mammoth conversion output of the uploaded document).
Severity rationale
- AV:L — requires local access to the host that runs Etherpad. Multi-tenant hosts (shared dev boxes, k8s shared-node setups, single-server CI workers) are the realistic threat surface.
- AC:H — attacker needs to predict the temp filename, which requires observing prior names or shared PRNG state.
- PR:L — any unprivileged local account.
- UI:N — no user interaction.
- S:C — scope change from local user to whatever the Etherpad process can write.
- C:L / I:L / A:N — bounded by what the Etherpad process can already touch; confidentiality is via secondary read-paths (the LibreOffice conversion error log can echo bytes from the symlinked file).
Single-tenant deployments where only the Etherpad operator has shell access on the host are not exposed.
Affected versions
- All
ep_etherpad-liteversions throughv3.0.0(inclusive). TheMath.floor(Math.random() * 0xFFFFFFFF)pattern is present insrc/node/handler/ImportHandler.tsandsrc/node/handler/ExportHandler.tsfor as far back as the repository history extends — older than the 2024-03-16 snapshot at commit107598bwhere it first appears in the current file paths, and predating the v1.x era.
Patched versions
ep_etherpad-lite >= 3.1.0— the fix is ondevelopHEAD as commit8c6104c. Update this field with the actual tagged release version when it ships.
Proof of concept (sketch)
# Pre-condition: attacker has shell on the same host as Etherpad,
# has read access to /tmp, and Etherpad's process can write to the
# chosen target (e.g. runs as root inside a Docker container).
# 1. Observe a temp filename from logs (or guess via prior exports).
TARGET=/etc/etherpad/SESSIONKEY.txt
GUESS=/tmp/etherpad_export_$(./predict-next-random)$EXT # implementation-specific
# 2. Place the symlink before Etherpad creates the file.
ln -s "$TARGET" "$GUESS"
# 3. Trigger an export from the Etherpad UI (or via the API).
# Etherpad calls fs.writeFile(srcFile, ...) which open()s the symlink
# target with O_WRONLY|O_TRUNC and clobbers $TARGET with HTML content.
In practice the exact reproduction depends on the host's…
- Record
GHSA-2jwf-f4xq-f24h- CVSS 3.1
- 4.2 Medium
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:N - Weakness
- CWE-59, CWE-377
- Updated
- 2026-11-02
NVD
4.2
Etherpad is a real-time collaborative editor. Prior to 3.1.0, src/node/handler/ImportHandler.ts and src/node/handler/ExportHandler.ts derive temporary filenames from Math.random() and place them in os.tmpdir(). On a host with a shared world-writable temporary directory, a local unprivileged attacker who predicts a filename can precreate a symbolic link to a file writable by the Etherpad process. Subsequent import or export operations can follow the link through fs.writeFile, fs.rename, or document-conversion output and overwrite the target with partially attacker-controlled content. This issue is fixed in version 3.1.0.
- Record
CVE-2026-55086- CVSS 3.1
- 4.2 Medium
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:N - Weakness
- CWE-59, CWE-377
- Updated
- 2026-11-02
OSV
4.2
Etherpad: Import/export use Math.random() for temp file paths; predictable paths on shared /tmp enable symlink-based file overwrite
Etherpad is a real-time collaborative editor. Prior to 3.1.0, src/node/handler/ImportHandler.ts and src/node/handler/ExportHandler.ts derive temporary filenames from Math.random() and place them in os.tmpdir(). On a host with a shared world-writable temporary directory, a local unprivileged attacker who predicts a filename can precreate a symbolic link to a file writable by the Etherpad process. Subsequent import or export operations can follow the link through fs.writeFile, fs.rename, or document-conversion output and overwrite the target with partially attacker-controlled content. This issue is fixed in version 3.1.0.
- Record
CVE-2026-55086- CVSS 3.1
- 4.2 Medium
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:N - Weakness
- CWE-377, CWE-59
- Updated
- 2026-11-02
OSVGHSA-2jwf-f4xq-f24h
4.2
ep_etherpad-lite: Import/export uses Math.random() for temp file paths; predictable paths on shared /tmp enable symlink-based file overwrite
Description
src/node/handler/ImportHandler.ts and src/node/handler/ExportHandler.ts both compute their temporary working-file paths as:
const randNum = Math.floor(Math.random() * 0xFFFFFFFF);
const srcFile = `${os.tmpdir()}/etherpad_export_${randNum}.html`;
const destFile = `${os.tmpdir()}/etherpad_export_${randNum}.${type}`;
Two flaws compound:
-
Math.random()is not crypto-secure. It yields at most ~32 bits of entropy and is predictable across calls within the same Node process (V8 shares PRNG state between consecutiveMath.random()invocations). An attacker on the same host who observes any earlier temp-file name from logs or other side channels can predict subsequent names. -
The paths land in
os.tmpdir(). On a typical Linux system this is/tmp— a shared world-writable directory. An unprivileged local attacker can pre-create a symbolic link at a predicted path pointing at any file the Etherpad process can write:ln -s /etc/etherpad/SESSIONKEY.txt /tmp/etherpad_export_<predicted>.htmlWhen
ExportHandlercallsfs.writeFile(srcFile, html)(orImportHandlercallsfs.rename(srcFile, destFile)/sofficewrites its converted output to the path), the open syscall follows the symlink and either reads from or overwrites the linked target. For deployments where the Etherpad process runs as a privileged user (notably some Docker base images that run as root, snap confinement edge cases, or hand-rolled systemd units), this becomes arbitrary file overwrite.
The Import path is more impactful in practice: the file content the attacker can land in the symlink target is partially attacker-controlled (the post-soffice/post-mammoth conversion output of the uploaded document).
Severity rationale
- AV:L — requires local access to the host that runs Etherpad. Multi-tenant hosts (shared dev boxes, k8s shared-node setups, single-server CI workers) are the realistic threat surface.
- AC:H — attacker needs to predict the temp filename, which requires observing prior names or shared PRNG state.
- PR:L — any unprivileged local account.
- UI:N — no user interaction.
- S:C — scope change from local user to whatever the Etherpad process can write.
- C:L / I:L / A:N — bounded by what the Etherpad process can already touch; confidentiality is via secondary read-paths (the LibreOffice conversion error log can echo bytes from the symlinked file).
Single-tenant deployments where only the Etherpad operator has shell access on the host are not exposed.
Affected versions
- All
ep_etherpad-liteversions throughv3.0.0(inclusive). TheMath.floor(Math.random() * 0xFFFFFFFF)pattern is present insrc/node/handler/ImportHandler.tsandsrc/node/handler/ExportHandler.tsfor as far back as the repository history extends — older than the 2024-03-16 snapshot at commit107598bwhere it first appears in the current file paths, and predating the v1.x era.
Patched versions
ep_etherpad-lite >= 3.1.0— the fix is ondevelopHEAD as commit8c6104c. Update this field with the actual tagged release version when it ships.
Proof of concept (sketch)
# Pre-condition: attacker has shell on the same host as Etherpad,
# has read access to /tmp, and Etherpad's process can write to the
# chosen target (e.g. runs as root inside a Docker container).
# 1. Observe a temp filename from logs (or guess via prior exports).
TARGET=/etc/etherpad/SESSIONKEY.txt
GUESS=/tmp/etherpad_export_$(./predict-next-random)$EXT # implementation-specific
# 2. Place the symlink before Etherpad creates the file.
ln -s "$TARGET" "$GUESS"
# 3. Trigger an export from the Etherpad UI (or via the API).
# Etherpad calls fs.writeFile(srcFile, ...) which open()s the symlink
# target with O_WRONLY|O_TRUNC and clobbers $TARGET with HTML content.
In practice the exact reproduction depends on the host's…
- Record
GHSA-2jwf-f4xq-f24h- CVSS 3.1
- 4.2 Medium
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:N - Weakness
- CWE-377, CWE-59
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
ep_etherpad-litenpm |
through 3.0.0 | 3.1.0 |
ep_etherpad-litenpm |
before 3.1.0 | 3.1.0 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-55086 is a medium vulnerability (CVSS 4.2) in Ether Etherpad, published August 13, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.14%, the 3rd percentile. Fixed in ep_etherpad-lite 3.1.0.
References
github.com/ether/etherpad/security/advisories/GHSA-2jwf-f4xq-f24h
github.com/ether/etherpad/pull/7784
github.com/ether/etherpad/commit/8c6104c5d5daf41f0d454acc04d42dffa0e0d996
github.com/ether/etherpad/releases/tag/v3.1.0
github.com/advisories/GHSA-2jwf-f4xq-f24h
github.com/CVEProject/cvelistV5/tree/main/cves/2026/55xxx/CVE-2026-55086.json
nvd.nist.gov/vuln/detail/CVE-2026-55086
github.com/ether/etherpad
Left out here: the rest of 2 source descriptions. The JSON record has them.