Skip to main content
Vulnerability Database/CVE-2025-62175

CVE-2025-62175: Mastodon Auth Bypass Vulnerability

CVE-2025-62175 is an authentication bypass flaw in Mastodon that allows suspended accounts to maintain streaming API access. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2025-62175 Overview

Mastodon is a free, open-source social network server based on the ActivityPub protocol. CVE-2025-62175 affects Mastodon versions before 4.4.6, 4.3.14, and 4.2.27. Disabling or suspending a user account does not disconnect that account from the streaming API. Suspended or disabled accounts continue receiving real-time updates through existing streaming connections. They can also establish new streaming connections, even though other API endpoints correctly reject them. The flaw undermines moderation actions, since administrators expect suspended accounts to lose all service access. The issue maps to [CWE-273: Improper Check for Dropped Privileges].

Critical Impact

Suspended or disabled Mastodon accounts retain real-time streaming access, bypassing moderator enforcement and continuing to receive timeline events.

Affected Products

  • Mastodon versions prior to 4.2.27
  • Mastodon versions prior to 4.3.14
  • Mastodon versions prior to 4.4.6

Discovery Timeline

  • 2025-10-13 - CVE-2025-62175 published to the National Vulnerability Database (NVD)
  • 2026-06-17 - Last updated in NVD database

Technical Details for CVE-2025-62175

Vulnerability Analysis

Mastodon exposes a WebSocket-based streaming API that pushes timeline and notification events to authenticated clients in real time. Authorization for this API is handled separately from the REST endpoints. The streaming layer validated only that the OAuth access token was not revoked and that the associated user was not marked disabled. It did not verify that the linked account was not suspended. As a result, a moderator action that suspended or disabled an account left existing streaming sessions intact and permitted new connections against the same token.

This is a broken access control condition rather than a memory safety flaw. The impact is limited to confidentiality of streamed content and the integrity of moderation workflows. Suspended users cannot post or interact through REST endpoints, but they continue to observe activity in real time.

Root Cause

The streaming service's account resolution query in streaming/index.js joined oauth_access_tokens to users but never joined the accounts table. Suspension state lives on the accounts record, so the query returned a valid session even after suspension. Additionally, the Account::Suspensions concern did not publish a kill event to Redis to terminate active streaming subscribers when a suspension was applied.

Attack Vector

An attacker holding a valid OAuth token for an account that is later suspended or disabled can continue to consume the streaming API. The attack requires low privileges (an existing user token) and no user interaction. Exploitation is trivial: reuse the token against the streaming endpoint after the suspension takes effect.

ruby
# Patch: app/models/concerns/account/suspensions.rb
# Publishes a kill event that terminates active streaming connections
# for the suspended account.
     update!(suspended_at: date, suspension_origin: origin)
     create_canonical_email_block! if block_email
   end
+
+    # This terminates all connections for the given account with the streaming
+    # server:
+    redis.publish("timeline:system:#{id}", Oj.dump(event: :kill)) if local?
   end

   def unsuspend!

Source: Mastodon commit 2971ac9

javascript
// Patch: streaming/index.js
// Adds a join to accounts and filters out suspended accounts during
// token-to-account resolution.
const result = await pgPool.query(
  'SELECT oauth_access_tokens.id, oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes ' +
  'FROM oauth_access_tokens ' +
  'INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id ' +
  'INNER JOIN accounts ON accounts.id = users.account_id ' +
  'WHERE oauth_access_tokens.token = $1 ' +
    'AND oauth_access_tokens.revoked_at IS NULL ' +
    'AND users.disabled IS FALSE ' +
    'AND accounts.suspended_at IS NULL ' +
  'LIMIT 1',
  [token]
);

Source: Mastodon commit 2971ac9

Detect Identity Attacks the Moment Authentication Fails

Singularity™ Identity surfaces credential misuse, lateral movement, and privilege escalation in real time, so you can contain the breach before it spreads.

Stop Identity Attacks

Detection Methods for CVE-2025-62175

Indicators of Compromise

  • Active WebSocket connections to /api/v1/streaming/* originating from OAuth tokens whose owning account has suspended_at set.
  • Streaming subscribers for timeline:* Redis channels tied to account_id values that appear as suspended in the accounts table.
  • HTTP 200 responses on streaming endpoints paired with HTTP 403 responses on REST endpoints for the same bearer token.

Detection Strategies

  • Correlate the accounts.suspended_at field with active session data from the streaming service to identify sessions that should have terminated.
  • Audit reverse proxy or load balancer logs for long-lived streaming connections that persist across moderation events.
  • Review oauth_access_tokens records associated with suspended users and flag any that show recent activity against /api/v1/streaming/.

Monitoring Recommendations

  • Enable structured logging in the Node.js streaming service and forward events to a centralized log store for query and retention.
  • Alert when a suspended account continues to consume streaming events for more than a short grace window after the moderation action.
  • Track Redis publish volume on timeline:system:* channels to confirm that kill events are being emitted after suspensions.

How to Mitigate CVE-2025-62175

Immediate Actions Required

  • Upgrade Mastodon to 4.4.6, 4.3.14, or 4.2.27 depending on the release branch in use.
  • After upgrading, revoke and reissue OAuth tokens for any account that was suspended while running a vulnerable version.
  • Review moderation logs since deployment of the affected version to identify accounts that may have retained streaming access post-suspension.

Patch Information

The fix is delivered in commit 2971ac9863b91372e68ac152caf6f4dbff511d17 and documented in GitHub Security Advisory GHSA-r2fh-jr9c-9pxh. The patch modifies the streaming token lookup to join the accounts table and filter on suspended_at IS NULL, and it publishes a Redis kill event on suspension to close existing streaming sockets.

Workarounds

  • No known workarounds exist. The upstream advisory states that upgrading is the only remediation.
  • Operators who cannot upgrade immediately should manually revoke OAuth tokens for suspended accounts to force disconnection.
bash
# Verify the installed Mastodon version on a server deployment
cd /home/mastodon/live
cat lib/mastodon/version.rb | grep -E "MAJOR|MINOR|PATCH"

# Upgrade example using git for a source-based install
git fetch --tags
git checkout v4.4.6   # or v4.3.14 / v4.2.27
RAILS_ENV=production bundle install
RAILS_ENV=production yarn install
RAILS_ENV=production bundle exec rails db:migrate
RAILS_ENV=production bundle exec rails assets:precompile
sudo systemctl restart mastodon-web mastodon-sidekiq mastodon-streaming

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.