Skip to content

messaging: inbound CorrelationId reaches logs and spans unvalidated #1101

Description

@gaborage

ADR-070 hardened the header half of the consume path — X-Request-ID, traceparent and tracestate are validated at trace.ExtractFromHeaders. The AMQP property half has no gate.

A delivery's own CorrelationId is read raw at two sinks:

  • messaging/registry.go — the amqp_correlation_id log field on the failure and panic lines (the field C60.7 introduced).
  • messaging/registry.go — the messaging.message.conversation_id span attribute.

A foreign publisher — anything that is not GoBricks, since our own publisher's value is validated at the assignment site — can put up to the full 255-byte shortstr there, any bytes the AMQP wire format accepts, and both sinks take it verbatim. That is a log-poisoning and dashboard-cardinality surface, not a crash: the shortstr length limit is what protects the connection, and it is the publisher's own connection that would break, not ours.

Symmetry argument for closing it: the framework already refuses to emit an unvalidated identifier into CorrelationId (ADR-070, and #1099 keeps that guard on the aligned value). Accepting one unconditionally on the way in is the same value class judged by a different standard.

Shape of a fix: run trace.ValidateRequestID over delivery.CorrelationId before it reaches either sink, and fall back to the framework's own trace id — the same substitute-rather-than-truncate rule ADR-070 states. Silent-behavior change; wants a migration atom, since a query over amqp_correlation_id would stop seeing the foreign values.

Found during the security gate on #1099; out of that PR's scope.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/messagingAffects the messaging packagebugSomething isn't workingready-for-agentFully specified, ready for an AFK agent

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions