Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
📦
📦 npm
Not in CISA KEV
MEDIUM severity

GHSA-vqfp-p66c-xrp9 ep_etherpad-lite

MEDIUMFix: ether/etherpad#7784

GHSA-vqfp-p66c-xrp9 is a medium-severity (CVSS 6.8) Information Exposure vulnerability in ep_etherpad-lite. A fix is available for ep_etherpad-lite — see the affected versions and patch details below.

ep_etherpad-lite: Device-to-device author-token transfer endpoint is replayable, never expires, and exposes the cleartext author token

Also known asCVE-2026-55088
Published
Aug 13, 2026
Updated
Aug 13, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Sep 20, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

No confirmed exploitation observed yet

  • A successful exploit gives an attacker total control of the affected component, not partial access.
  • CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.

Exploitation and automatability from CISA’s SSVC triage for GHSA-vqfp-p66c-xrp9.

EPSS Exploitation Probability

via FIRST.org ↗
0.4%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs30th percentile — riskier than 30% of all scored CVEsHighest risk

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

How urgent is this, really

GHSA-vqfp-p66c-xrp9 plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.

Where this sits among everything scored

Of 377,238 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.

Real-World Exposure

1 pkg affected

How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.

2other npm packages depend on this — each one inherits the vulnerability until it's patched upstream
ep_etherpad-litenpm
197downloads / week

Description

Etherpad's device-to-device author-token transfer endpoint is replayable, never expires, and exposes the cleartext author token in the GET response body

Description

Etherpad ships an endpoint pair under /tokenTransfer (src/node/hooks/express/tokenTransfer.ts) that lets a logged-in user move their HttpOnly author token to a different browser (typically by scanning a QR code containing the transfer URL). The flow is:

  1. POST /tokenTransfer — the source device sends a request whose own author cookie is read off the server-side cookie jar. The server mints a random UUID and stores the author token (and arbitrary prefsHttp field) under a DB key keyed by that UUID. The UUID is returned.
  2. GET /tokenTransfer/{uuid} — the destination device GETs the URL containing the UUID. The server reads the stored record and sets the HttpOnly author cookie on the response.

The original implementation has three serious flaws:

  1. No expiration check. createdAt is written to the record on POST but never inspected on GET. A leaked transfer URL is redeemable indefinitely.
  2. No single-use enforcement. The DB record is not deleted after a successful GET, so the same URL can be redeemed repeatedly — each redemption yielding a fresh cookie set on whoever issued the GET.
  3. Author token echoed in the response body. The GET handler ends with res.send(tokenData), which serializes the full record — including the raw author token — into the JSON response. Any JavaScript on the page that issued the GET can read the token, defeating the HttpOnly cookie design that exists specifically to keep the token out of JS reach.

Combined, these mean that any disclosure of a transfer UUID (browser history, mis-shared QR code, screenshot, server log, third-party plugin that proxies the request, an unencrypted intermediate hop) results in persistent authorship impersonation of the originating account — the attacker doesn't just get one cookie, they can re-redeem and they get the raw token in cleartext for storage / replay against other endpoints.

Severity rationale

  • AV:N — exploitable over the network.
  • AC:H — requires the attacker to learn the transfer UUID via some out-of-band channel; UUIDs are random.
  • PR:N — no authentication required at the redemption endpoint.
  • UI:R — the legitimate user must have issued the POST and the UUID must end up where the attacker can see it (QR code, screenshot, etc.).
  • C:H / I:H — full author identity takeover (read + write everything that author can).
  • A:N — no direct denial-of-service.

CVSS lands at 7.5 (High). Some operators may reasonably score this lower (UI:R + AC:H) if their threat model assumes the transfer URL never leaves the user's own device pair.

Affected versions

Patched versions

  • ep_etherpad-lite >= 3.1.0 — the fix is on develop HEAD as commit 8c6104c. Update this field with the actual tagged release version when it ships.

Proof of concept

# 1. Victim posts a transfer from their device.
curl -X POST https://pad.example/tokenTransfer \
  -H 'Cookie: token=t.victim-author-token' \
  -H 'Content-Type: application/json' \
  -d '{"prefsHttp": ""}'
# -> {"id": "1f0b2a3c-..."}

# 2. UUID leaks (browser history, intercepted QR, etc.).
# 3. Attacker redeems it from a totally different machine:
curl -i https://pad.example/tokenTransfer/1f0b2a3c-...
# Headers include:
#   Set-Cookie: token=t.victim-author-token; Path=/; HttpOnly; ...
# Body contains:
#   {"token":"t.victim-author-token", "prefsHttp": "", "createdAt": ...}
#
# Attacker now owns the victim's identity. They can also re-redeem the
# same UUID (no single-use), and the body gives them the cleartext token
# even if the HttpOnly cookie isn't useful to their tooling.

Workarounds

  • Disable any UI that surfaces the transfer URL (QR code, copy-button, etc.).
  • Reverse-proxy block /tokenTransfer/* if device-pairing is not in use.
  • Set short DB cleanup intervals (does not address the JS-readable body issue).

None of these workarounds are sufficient on their own — upgrade is the only complete fix.

Fix

Patched in 8c6104c (PR #7784):

  1. 5-minute TTL (TRANSFER_TTL_MS). Records older than this return 410 Gone. Records with absent/non-numeric createdAt (legacy records from older code paths) are treated as expired.
  2. Single-use. The DB record is removed before the success response is written, so a parallel request that wins the race observes an already-redeemed transfer rather than a second usable copy.
  3. Body sanitised. The response body becomes {ok: true, prefsHttp} — the raw author token is no longer included. The HttpOnly cookie set in the same response is the only delivery channel.
- const tokenData = await db.get(`${tokenTransferKey}:${id}`);
+ const key = tokenTransferKey(id);
+ const tokenData: TokenTransferRequest | undefined = await db.get(key);
  if (!tokenData) {
    return res.status(404).send({error: 'Token not found'});
  }
+ await db.remove(key);
+ const createdAt = typeof tokenData.createdAt === 'number'
+     ? tokenData.createdAt : 0;
+ if (Date.now() - createdAt > TRANSFER_TTL_MS) {
+   return res.status(410).send({error: 'Token expired'});
+ }
  ...
- res.send(tokenData);
+ res.send({ok: true, prefsHttp: tokenData.prefsHttp});

Resources

  • Patched in: https://github.com/ether/etherpad/pull/7784 (squash commit 8c6104c).
  • Vulnerable code introduced in: https://github.com/ether/etherpad/commit/41cb680 (PR #7228), released in v2.6.0.
  • Background on the HttpOnly author-token migration: ether/etherpad PR #7548 (PR3 of #6701, released in v2.7.3). That earlier PR addressed two adjacent issues (the cookie was previously non-HttpOnly, and the POST handler previously trusted the request body for the token value). This GHSA covers only the three flaws that remained after that earlier patch.

Credits

Reported during an internal security audit by Claude (via @JohnMcLear).

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
📦npmep_etherpad-lite2.6.0&&< 3.1.03.1.0npm install ep_etherpad-lite@3.1.0

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for ep_etherpad-lite, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update ep_etherpad-lite to 3.1.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-vqfp-p66c-xrp9 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like GHSA-vqfp-p66c-xrp9 can be triaged on real exposure rather than presence alone.

Tailored to GHSA-vqfp-p66c-xrp9. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

Etherpad's device-to-device author-token transfer endpoint is replayable, never expires, and exposes the cleartext author token in the GET response body ## Description Etherpad ships an endpoint pair under `/tokenTransfer` (`src/node/hooks/express/tokenTransfer.ts`) that lets a logged-in user move their HttpOnly author token to a different browser (typically by scanning a QR code containing the transfer URL). The flow is: 1. **POST `/tokenTransfer`** — the source device sends a request whose own author cookie is read off the server-side cookie jar. The server mints a random UUID and stores
O3 Security · Impact-Aware SCA

Is GHSA-vqfp-p66c-xrp9 in your dependencies?

O3 Security finds GHSA-vqfp-p66c-xrp9 across npm dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.

GHSA-vqfp-p66c-xrp9: ep_etherpad-lite | O3 Security