html-embed: close collab broadcast window (transient embed executes in concurrent editors before persist strip) #26

Closed
opened 2026-06-20 20:31:53 +03:00 by Ghost · 0 comments

Found in security review of PR #16 (merged in 7a03321d).

Severity: medium (accepted residual risk).

The admin gate strips htmlEmbed in the debounced onStoreDocument (persist), but Hocuspocus broadcasts each inbound Yjs update to connected clients immediately. So a non-admin editor with Edit rights can make a transient htmlEmbed execute in the browsers of OTHER authenticated editors who have the same doc open in the editable editor, in the window before the persist strips it.

  • File: apps/server/src/collaboration/extensions/persistence.extension.ts (~L140-180, already documented in-code as accepted).
  • Impact: XSS against concurrent authenticated, edit-capable space members only. Confirmed it CANNOT reach the persisted page row or anonymous public-share/readonly viewers (they do not open a collab socket; only page-editor.tsx instantiates HocuspocusProvider).
  • Requires: feature toggle ON + attacker is an authenticated member with Edit rights + a victim with the same doc open in the editable editor. Transient.

Fix options: add an inbound onChange/beforeBroadcast strip so a non-admin's htmlEmbed never broadcasts, OR formally sign off this as an accepted risk (move the acceptance out of a code comment into a tracked decision).

Found in security review of PR #16 (merged in 7a03321d). **Severity: medium (accepted residual risk).** The admin gate strips `htmlEmbed` in the debounced `onStoreDocument` (persist), but Hocuspocus broadcasts each inbound Yjs update to connected clients immediately. So a non-admin editor with Edit rights can make a transient `htmlEmbed` execute in the browsers of OTHER authenticated editors who have the same doc open in the editable editor, in the window before the persist strips it. - File: `apps/server/src/collaboration/extensions/persistence.extension.ts` (~L140-180, already documented in-code as accepted). - Impact: XSS against concurrent authenticated, edit-capable space members only. Confirmed it CANNOT reach the persisted page row or anonymous public-share/readonly viewers (they do not open a collab socket; only `page-editor.tsx` instantiates HocuspocusProvider). - Requires: feature toggle ON + attacker is an authenticated member with Edit rights + a victim with the same doc open in the editable editor. Transient. **Fix options:** add an inbound `onChange`/`beforeBroadcast` strip so a non-admin's htmlEmbed never broadcasts, OR formally sign off this as an accepted risk (move the acceptance out of a code comment into a tracked decision).
Ghost added the bugsecurity labels 2026-06-21 02:27:20 +03:00
Ghost closed this issue 2026-06-21 03:02:06 +03:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: vvzvlad/gitmost#26