High, CVSS 7.1GoAmendedPublished
Convoy: Cross-Tenant Source IDOR Leaks Plaintext Message Broker Credentials
CVE-2026-81505 · GHSA-p5vg-v7mj-f6q4
- Affected
- Go github.com/frain-dev/convoy < 0.9.3-0.20260724092134-1cc67cd16fb1
- Fixed in
- 0.9.3-0.20260724092134-1cc67cd16fb1· Vendor fix available
- Issue
- frain-dev/convoy (all versions up to and including v26.6.2, no patch available) lets any authenticated caller who is authorized on at least one project read ANY OTHER project's "Source" record by ID via GET /api/v1/projects/{projectID}/sources/{sourceID} -- regardless of whether that Source actually belongs to the project named in the URL. The response includes the Source's full PubSub broker configuration in plaintext (AMQP/Kafka/SQS/Google credentials), with no redaction. Details Handler.GetSource (api/handlers/source.go) resolves the caller's authorization against the {projectID} in the URL via retrieveProject(), then calls sources.Service.FindSourceByID(ctx, project.UID, sourceID) (internal/sources/impl.go). That function accepts a projectID parameter but never uses it: func (s Service) FindSourceByID(ctx context.Context, projectID, id string) (datastore.Source, error) { row, err := s.repo.FetchSourceByID(ctx, common.StringToPgText(id)) ... } The underlying SQL query…
Recommended action: Upgrade to 0.9.3-0.20260724092134-1cc67cd16fb1 (pre-release) or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.