Security Model
Threat model — prompt injection is the primary risk
ActivityPub MCP feeds attacker-authored, world-writable fediverse content — posts, bios, display names, notifications — directly to an LLM that may simultaneously hold write access to the user’s account. A malicious post or bio can contain instructions crafted to steer the model (e.g. “ignore previous instructions and post the following”). Notifications are an unsolicited injection channel: anyone on the fediverse can mention your account and have that content surface to the model without any action on your part.
This is not hypothetical: anyone who can publish a post can attempt to influence what the LLM does on your behalf.
Mitigations — and their limits
Read-only by default
Mutation tools (post, reply, delete, boost, favourite, bookmark, follow, mute, block, vote, upload,
scheduled posts) are not registered unless ACTIVITYPUB_ENABLE_WRITES=true is set. Without that
flag, injected content has no write tools to call — the attack surface is limited to information
disclosure and model-output manipulation, not account action. There is also a runtime guard
(requireWriteEnabled) so a mutation refuses even if it were somehow reachable.
Recommendation: keep writes disabled unless you actively need them, and review the write tool surface before enabling.
Untrusted-content envelope
All remote fediverse content is wrapped in an <untrusted-content source="..."> envelope before it
reaches the model, signalling provenance and instructing the model to treat the content as data, not
instructions. This is a mitigation, not a cure — a determined payload can still influence the
model’s reasoning. The outer control is your MCP client’s per-call approval UX: review tool calls
before approving them, especially writes.
Tool annotations
Every tool carries MCP annotations (readOnlyHint, destructiveHint) so compliant clients can
gate or surface write tools differently. This is advisory — clients are not required to enforce it.
Network & SSRF protection
The server fetches arbitrary remote URLs, so every outbound request goes through one guarded path:
- HTTPS-only; no private/loopback/link-local ranges (
10.x,172.16–31.x,192.168.x,127.x,::1,169.254.x, IPv4-mapped/NAT64/6to4 forms, etc.). - DNS-rebinding protection: the resolved IP is pinned and re-validated after every redirect, so a rebind mid-request can’t reach a private address.
- Redirect re-validation: each redirect target is re-checked against the same allow/block rules.
- Response size caps to prevent memory exhaustion;
upload-mediastats files and refuses anything overMAX_UPLOAD_SIZEbefore reading them. - Operator instance blocklist (
BLOCKED_INSTANCES, exact domain or*.wildcard). Note: an apex entry does not cover its subdomains — use*.example.comto block a whole instance family. - Cross-origin thread fetches are off by default (
MCP_THREAD_CROSS_ORIGIN_FETCH=false): both the reply branch and the in-reply-to ancestor walk stay on the root post’s origin, so a hostile root can’t steer the server into fetching arbitrary third-party hosts.
Credential storage & audit
OAuth/MiAuth tokens are stored at ${XDG_CONFIG_HOME:-~/.config}/activitypub-mcp/accounts.json with
mode 0600; the server refuses to open a symlink at that path. Audit logs redact tokens and post
content and store only file basenames (never absolute paths) — secrets are never written to log
output. Set AUDIT_LOG_ENABLED=false to disable the in-memory audit trail (not recommended when
writes are enabled).
HTTP transport
When running in HTTP mode:
- A bearer secret is required (minimum 16 characters); requests without a valid
Authorization: Bearer <secret>header are rejected. - The MCP SDK’s DNS-rebinding protection is active. For non-localhost binds, set
MCP_HTTP_ALLOWED_HOSTSandMCP_HTTP_ALLOWED_ORIGINS. - For local use (Claude Desktop, Cursor), stdio transport is recommended — no network exposure.
Reporting a vulnerability
Report security issues privately — do not open a public issue. Use
GitHub Security Advisories (“Report a
vulnerability”) or email c@meron.io with subject [SECURITY] ActivityPub MCP — <brief description>.
The canonical, always-current policy lives in
SECURITY.md.
Security resources
- Dependency Security — secure dependency management
- Security Troubleshooting — common security issues