Описание
AMQP 1.0 post-body properties bypass user-ID validation and reach consumers
Summary
RabbitMQ's AMQP 1.0 server parser stops as soon as it encounters the first message body section. It does not validate the remaining message section order. The unparsed tail is stored and forwarded byte-for-byte.
An authenticated AMQP 1.0 publisher can send a valid body followed by a
properties section containing a forged user-id. RabbitMQ treats the
message as having no user-id when it executes its authenticated publisher
check. Downstream AMQP 1.0 clients that do not enforce section ordering parse
the late properties and expose the forged identity to the consumer. RabbitMQ's
AMQP 1.0-to-0-9-1 conversion path also installs the late properties, exposing
the forged user-id to AMQP 0-9-1 consumers.
This creates a message parser differential across RabbitMQ's validation boundary:
The repository's own AMQP 1.0 client accepts properties after the body and
exposes the forged user-id.
Affected revision
Confirmed against:
Confirmed with Erlang/OTP 27.
The affected release range has not been established. This report only claims the revision above.
Affected components
deps/amqp10_common/src/amqp10_binary_parser.erldeps/rabbit/src/mc_amqp.erldeps/rabbit/src/rabbit_amqp_session.erldeps/rabbit/src/rabbit_access_control.erldeps/amqp10_client/src/amqp10_msg.erl
Attack requirements
- The attacker can authenticate to RabbitMQ over AMQP 1.0
- The attacker has write permission to a target exchange or queue
- A victim consumes the message through an AMQP 1.0 decoder that accepts known sections after the body, or through a cross-protocol conversion path that decodes the complete bare message
- The victim uses the message
user-idor other late metadata as an authenticated identity signal
The attacker does not need the RabbitMQ impersonator tag. The broker never
observes the forged field during check_user_id.
AMQP section-order violation
AMQP 1.0 message sections have a defined order. Properties belong before application properties and before all body sections. The proof of concept sends:
The payload is:
Decoded:
A normal order-insensitive decoder returns:
Root cause
In server_mode, the parser returns immediately when the first body
descriptor is recognized:
reached_body/2 does not validate the body value or any trailing sections:
mc_amqp:init/1 uses this mode for inbound AMQP 1.0 messages:
The body marker causes msg_body_encoded/3 to preserve the entire remaining
payload:
The illegal post-body properties are therefore absent from the broker's
decoded properties record but remain present in bare_and_footer.
User-ID validation bypass
After message initialization, the AMQP session performs:
rabbit_access_control:check_user_id/2 explicitly permits an omitted
user-id:
If RabbitMQ had parsed the late properties, a non-impersonator authenticated as another user would be rejected:
Because the server parser stopped at the body, mc:user_id(Message) returns
undefined and validation succeeds.
Storage and forwarding
mc_amqp:prepare(store, ...) preserves bare_and_footer without reparsing.
End-to-end queue tests confirmed that classic, quorum, and stream queues retain
the late properties for AMQP 1.0 delivery. Classic and quorum queues also
retain them through AMQP 0-9-1 conversion.
When RabbitMQ sends the message to an AMQP 1.0 consumer,
mc_amqp:protocol_state/2 regenerates the header and message annotations but
appends the raw bare message unchanged:
The forwarded section sequence is therefore:
The illegal properties section remains visible to the consumer.
Consumer behavior
The RabbitMQ AMQP 1.0 client decodes all sections and folds them in wire order. Its message constructor does not enforce that properties precede the body:
When properties occur after data, the body is retained and the later
properties record is installed. The consumer sees {binary, <<"admin">>} as
the message user-id.
Strict clients that reject out-of-order sections are not vulnerable to identity spoofing, but they can reject or disconnect on the stored message.
Minimal deterministic proof of concept
After building the core broker from the repository root with
make -C deps/rabbit (gmake on systems where GNU Make is not the default),
run:
Expected output:
This minimal proof directly compares the identity seen by RabbitMQ's validation path with the identity exposed after storage serialization and normal consumer decoding.
Security impact
Confirmed:
- An internal user without the
impersonatortag can publish an arbitrary lateuser-idafter the body - RabbitMQ's publisher identity check sees the field as absent
- A legal-order control carrying the same mismatched
user-idis rejected - Classic, quorum, and stream queues preserve the late properties for AMQP 1.0 delivery
- The repository AMQP 1.0 client exposes the forged
user-idto applications - AMQP 0-9-1 conversion exposes the forged
user-idthrough classic and quorum queues
This can violate application-level integrity when consumers rely on RabbitMQ's
validated user-id semantics to identify the publisher.
This is a meaningful validation-boundary conflict despite the illegal section
order. RabbitMQ documents that when user-id is set, its value is validated
against the authenticated connection user, and that the administrator tag
does not permit forgery. Consumers can therefore reasonably treat a delivered
user-id as broker-validated. Strict AMQP 1.0 consumers that reject
out-of-order sections are not vulnerable to identity spoofing, but can reject
or disconnect on the stored entry.
The same parser differential can apply to other known sections placed after the body. For example, a late message-annotations section can disagree with the message annotations RabbitMQ parsed or generated. The precise impact depends on whether the downstream decoder accepts and prioritizes the later section.
Not demonstrated:
- Broker exchange or routing-key manipulation
- Resource or topic authorization bypass
- Publishing to an unauthorized destination
- RabbitMQ node compromise
- Remote code execution
RabbitMQ routing and authorization use only metadata parsed before the body. The issue changes the metadata observed by downstream consumers, not the broker's routing decision.
Severity
Suggested severity: moderate when validated user-id is used as a security or
audit identity by downstream consumers.
The attack requires an authenticated publisher with write permission, but it
allows that publisher to impersonate another RabbitMQ username to consumers
without the impersonator tag.
Severity is lower where consumers ignore user-id, treat all message
properties as untrusted application input, or enforce AMQP section ordering
independently.
Recommended remediation
- Continue scanning after the first body marker sufficiently to validate legal section ordering
- Reject properties, application-properties, annotations, or headers that occur after a body section
- Reject a second body kind or any non-footer section after the body sequence
- Validate the body value and footer rather than treating the entire tail as opaque untrusted bytes
- Ensure
check_user_idis based on the same canonical message interpretation delivered to consumers - Make the AMQP client reject illegal section ordering and duplicate singleton sections
An optimized implementation can still avoid materializing large body values. It only needs to walk encoded section boundaries safely and validate descriptor identity, cardinality, and order.
Regression tests
Add tests for:
- Data followed by properties containing another user's
user-id - Data followed by message annotations
- Data followed by application properties
- Data followed by header or delivery annotations
- Sequence followed by properties
- Value followed by properties
- Duplicate properties before the body
- Multiple legal data sections followed by footer
- Classic, quorum, and stream persistence
- Same-protocol AMQP 1.0 delivery
- Cross-protocol delivery
- A publisher with and without the
impersonatortag - Consumers using the repository AMQP 1.0 client
The primary assertion should compare:
These values must never differ.
Пакеты
rabbitmq
>= 4.3.0, < 4.3.5
4.3.5
5.3 Medium
CVSS4
Дефекты
5.3 Medium
CVSS4