Severity by source
AV:L/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:N
Local access and PRNG state reconstruction required (AV:L/AC:H/PR:L); scope change to Etherpad-process-owner files confirmed by symlink mechanics; no availability impact.
Primary rating from Vendor (https://github.com/ether/etherpad).
CVSS VectorVendor: https://github.com/ether/etherpad
Lifecycle Timeline
2DescriptionCVE.org
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 ExportHandler calls fs.writeFile(srcFile, html) (or ImportHandler calls fs.rename(srcFile, destFile) / soffice writes 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 PRNG state predictability and the deployment's process-owner privileges. A reliable exploit chain needs setpriv-style host access or a sibling tenant.
Workarounds
- Run Etherpad in a container with a private
/tmp(Docker:--tmpfs /tmp:rw,noexec,nosuid,nodev,size=64m, systemd:PrivateTmp=true). - Ensure the Etherpad process does NOT run as root and has write access only to its own data directory.
- Set
TMPDIRto an Etherpad-private directory in the environment.
Fix
Patched in 8c6104c (PR #7784):
-const randNum = Math.floor(Math.random() * 0xFFFFFFFF);
+const randNum = crypto.randomBytes(16).toString('hex');128 bits of CSPRNG entropy. Predicting the next filename is no longer feasible.
A bigger follow-up - per-request mkdtemp subdirectories with O_EXCL/O_NOFOLLOW semantics - is deferred to a later release; the immediate window (predictable 32-bit collisions across processes) is what the patch closes.
Resources
- Patched in: https://github.com/ether/etherpad/pull/7784 (squash commit
8c6104c). Math.random()is not appropriate for security-sensitive contexts. See the MDN guidance forMath.random()and the Node.js recommendation to usecrypto.randomBytesfor unpredictable values.
Credits
Reported during an internal security audit by Claude (via @JohnMcLear).
AnalysisAI
Predictable temporary file paths in Etherpad's import and export handlers expose multi-tenant deployments to a symlink-based file overwrite attack. All ep_etherpad-lite versions through v3.0.0 are affected; exploitation requires local host access, an unprivileged OS account, and - for high-impact scenarios - the Etherpad process running as root, a common default in many Docker base images. …
Unlock full vulnerability intelligence
- Risk assessment & exploitation conditions
- Attack chain visualization
- Remediation with exact patch versions
- Threat intelligence from 22 sources
- Personal watchlist & email alerts
Free forever · No credit card required
Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata
Vulnerability AssessmentAI
| Exploitation | Exploitation requires: (1) an unprivileged local OS account on the host running Etherpad (PR:L per the provided CVSS vector); (2) the ability to observe prior temp filenames via application logs, /tmp directory listing, or process monitoring in order to reconstruct sufficient V8 PRNG state to predict subsequent values (AC:H per the provided CVSS vector - this is the primary practical barrier); and (3) the Etherpad process running as a privileged user, typically root in default Docker base images, certain snap confinements, or hand-rolled systemd units without explicit User= directives, for the highest-impact file overwrite scenarios. … Additional conditions and limiting factors are described in the full assessment. |
| Risk Assessment | CVSS 3.1 scores this at 4.2 (Medium) with AV:L/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:N, which accurately reflects the real-world constraints: mandatory local shell access, the difficulty of PRNG state prediction (AC:H), and impact bounded by the Etherpad process owner's file permissions. … Full risk analysis with EPSS, KEV, and SSVC signal comparison available after sign-in. |
| Exploit Scenario | Full exploit scenario with step-by-step reproduction available after sign-in. |
| Remediation | Upgrade ep_etherpad-lite to version 3.1.0 or later, which replaces the insecure temp file naming with crypto.randomBytes(16).toString('hex') as patched in commit 8c6104c via PR #7784 (https://github.com/ether/etherpad/pull/7784). … Detailed patch versions, workarounds, and compensating controls in full report. |
Threat intelligence, references, and detailed analysis are available after sign-in.
An issue was discovered in Appsmith before 1.52. Rated critical severity (CVSS 9.8), this vulnerability is remotely expl
runc through version 1.0-rc6 (used in Docker before 18.09.2) contains a container escape vulnerability that allows attac
Netmaker makes networks with WireGuard. Rated high severity (CVSS 7.5), this vulnerability is remotely exploitable, no a
Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/
The News & Blog Designer Pack - WordPress Blog Plugin - (Blog Post Grid, Blog Post Slider, Blog Post Carousel, Blog Post
Path traversal in JFrog Artifactory (CWE-22) enables an authenticated low-privilege user to write data outside the inten
Docker 1.3.2 allows remote attackers to execute arbitrary code with root privileges via a crafted (1) image or (2) build
Remote code execution in Gogs through 0.14.2 allows authenticated users (and unauthenticated attackers on default-config
Remote code execution in Flowise before 3.1.2 allows any authenticated user (or API caller with chatflow view/update per
Remote code execution in NocoBase Workflow Script Node (npm @nocobase/plugin-workflow-javascript) allows authenticated l
Docker Desktop Community Edition before 2.1.0.1 allows local users to gain privileges by placing a Trojan horse docker-c
Vasion Print (formerly PrinterLogic) Virtual Appliance Host prior to version 25.2.169 and Application prior to version 2
Same weakness CWE-59 – Improper Link Resolution Before File Access
View allSame technique Information Disclosure
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-62741
GHSA-2jwf-f4xq-f24h