CVE-2026-67420 Overview
CVE-2026-67420 is a missing authorization vulnerability [CWE-862] in RabbitMQ, affecting versions from 3.13.0 up to the patched releases. When an existing Advanced Message Queuing Protocol (AMQP) connection refreshes its OAuth token, RabbitMQ updates the backend token data but leaves the connection's runtime #user.tags unchanged. A connection that previously held the impersonator tag can continue publishing messages with a foreign AMQP user_id after that privilege has been revoked.
Critical Impact
Connections that successfully refresh to a downgraded same-username OAuth token retain the stale impersonator tag, enabling continued message publishing under spoofed user_id values until the connection is closed.
Affected Products
- RabbitMQ versions 3.13.0 through 3.13.18
- RabbitMQ 4.0.x through 4.0.23, 4.1.x through 4.1.14, 4.2.x through 4.2.9
- RabbitMQ 4.3.x through 4.3.4 using rabbit_auth_backend_oauth2 or equivalent refresh-capable backends
Discovery Timeline
- 2026-09-25 - CVE-2026-67420 published to the National Vulnerability Database (NVD)
- 2026-09-29 - Last updated in NVD database
Technical Details for CVE-2026-67420
Vulnerability Analysis
The defect lives in RabbitMQ's credential-refresh path for OAuth-authenticated AMQP connections. When a token is refreshed, rabbit_access_control:update_state/2 updates the per-backend implementation state, including token, scopes, and expiry, but does not rebuild the composite #user.tags list stored on the connection record. Downstream, rabbit_access_control:check_user_id/2 consults those cached tags to decide whether a publisher may set an arbitrary AMQP user_id. Because the stale tag set survives the refresh, a connection that was granted the impersonator tag at authentication time retains the ability to publish messages under any other username, including through newly opened channels on the same connection.
Root Cause
The root cause is incomplete state reconciliation on authorization refresh. The refresh routine propagates updated backend implementations into the user record but never recomputes the aggregated tags field from the backends' returned values. A fresh connection using the downgraded token is correctly refused, which confirms the issue is stale session state rather than token validity.
Attack Vector
Exploitation requires a connection that was previously authenticated with an OAuth token granting the impersonator tag, followed by a successful refresh to a same-username token that no longer grants it. The authenticated holder of the downgraded token can then publish AMQP messages with a spoofed user_id using the long-lived connection, bypassing the authorization change until the connection is closed.
update_state(User = #user{authz_backends = Backends0}, NewState) ->
%% N.B.: we use foldl/3 and prepending, so the final list of
%% backends is in reverse order from the original list.
+ %%
+ %% Rebuild `#user.tags` from the refreshed backends. A refresh can revoke a
+ %% tag, for example `impersonator`, which is honoured by `check_user_id/2`,
+ %% so a stale tag set must not survive the refresh.
Backends = lists:foldl(
- fun({Module, Impl}, {ok, Acc}) ->
+ fun({Module, Impl}, {ok, Acc, TagsAcc, Refreshed}) ->
AuthUser = auth_user(User, Impl),
case Module:expiry_timestamp(AuthUser) of
never ->
- {ok, [{Module, Impl} | Acc]};
+ {ok, [{Module, Impl} | Acc], TagsAcc, Refreshed};
_ ->
case Module:update_state(AuthUser, NewState) of
- {ok, #auth_user{impl = Impl1}} ->
- {ok, [{Module, Impl1} | Acc]};
+ {ok, #auth_user{impl = Impl1, tags = Tags1}} ->
+ {ok, [{Module, Impl1} | Acc], TagsAcc ++ Tags1, true};
Else -> Else
end
end;
(_, {error, _} = Err) -> Err;
(_, {refused, _, _} = Err) -> Err
- end, {ok, []}, Backends0),
+ end, {ok, [], [], false}, Backends0),
case Backends of
- {ok, Pairs} -> {ok, User#user{authz_backends = lists:reverse(Pairs)}};
Source: GitHub Commit 5de287d. The patch adds a TagsAcc accumulator and a Refreshed flag so that #user.tags is rebuilt from the refreshed backends whenever at least one backend returns updated tags.
Detection Methods for CVE-2026-67420
Indicators of Compromise
- AMQP basic.publish frames carrying a user_id property that differs from the authenticated connection username, especially after a token refresh event.
- Long-lived AMQP connections whose associated OAuth tokens have undergone one or more refreshes while the broker runs an affected RabbitMQ version.
- Audit log entries showing successful OAuth refresh for a user whose scopes or tags were downgraded, followed by continued publishing activity.
Detection Strategies
- Compare each connection's current OAuth token tags with the tags enforced during check_user_id decisions and alert on any divergence.
- Correlate RabbitMQ connection, channel, and publisher metrics with identity provider revocation or scope-change events to surface stale sessions.
- Review broker logs for impersonator tag usage and cross-reference with the token payloads active at publish time.
Monitoring Recommendations
- Enable RabbitMQ's authentication and authorization logging and forward events to a centralized analytics platform for correlation with identity provider logs.
- Track the ratio of messages whose user_id property does not match the connection owner and alert on anomalous growth.
- Monitor for the presence of the impersonator tag across active connections and restrict its assignment to a minimal, audited set of principals.
How to Mitigate CVE-2026-67420
Immediate Actions Required
- Upgrade RabbitMQ to version 3.13.19, 4.0.24, 4.1.15, 4.2.10, or 4.3.5, matching the branch currently deployed.
- Terminate existing AMQP connections that were authenticated with tokens carrying the impersonator tag so they re-authenticate against the patched broker.
- Audit OAuth clients that are permitted to request the impersonator tag and remove the privilege wherever it is not strictly required.
Patch Information
The fix is tracked in GitHub Security Advisory GHSA-86fm-44m9-rqjx and shipped in the RabbitMQ v4.3.5 release. The patched rabbit_access_control:update_state/2 rebuilds #user.tags from the refreshed backends, ensuring revoked tags such as impersonator no longer survive a token refresh.
Workarounds
- Disable rabbit_auth_backend_oauth2 or any refresh-capable backend that returns tags until the patched release is deployed.
- Stop granting the impersonator tag through OAuth scopes and manage impersonation via static definitions reviewed out of band.
- Shorten OAuth access token lifetimes and force clients to reconnect rather than relying on in-connection refresh so authorization state is rebuilt from scratch.
# Verify installed RabbitMQ version and upgrade to a patched release
rabbitmqctl version
# Debian/Ubuntu example once the patched package is available in your repo
sudo apt-get update && sudo apt-get install --only-upgrade rabbitmq-server
# List active connections and forcibly close any that pre-date the upgrade
rabbitmqctl list_connections name user peer_host
rabbitmqctl close_connection "<connection-name>" "CVE-2026-67420 remediation"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

