highVulnerability

CVE-2026-81505

## Summary 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 (internal/sources/repo/queries.sql, `fetchSourceByID`) has no project_id predicate at all: SELECT ... FROM convoy.sources AS s LEFT JOIN convoy.source_verifiers sv ON s.source_verifier_id = sv.id WHERE s.id = $1 AND s.deleted_at IS NULL So the {projectID} in the URL only gates "is the caller authorized to view *a* project" -- it never re-validates that the fetched Source actually belongs to that project. `LoadSourcesPaged` (the list endpoint) does correctly scope by project; only the single-item GetSource lookup is affected. `SourceResponse{*datastore.Source}` embeds the full database record with no redaction, so if the leaked Source is an AMQP/Kafka type, its `pub_sub.*.auth.password` field (a live, plaintext broker credential) is returned verbatim. ## Proof of Concept 1. As a test account, create "Victim Project" and an AMQP Source in it with a known broker password (verified against a real RabbitMQ broker, not just stored -- Conv

Properties

ghsa_id
GHSA-p5vg-v7mj-f6q4
severity
high
summary
Convoy: Cross-Tenant Source IDOR Leaks Plaintext Message Broker Credentials
cve_id
CVE-2026-81505
signal_observed_at
2026-09-18T17:46:44+00:00
is_ghsa_only
false
ghsa_published
2026-09-18T17:17:45Z
source_url
https://github.com/advisories/GHSA-p5vg-v7mj-f6q4
ghsa_updated
2026-09-18T17:17:48Z

Related Entities (4)

VULNERABLE_TO (1)

[Software]go/github.com/frain-dev/convoy

AFFECTS (1)

[Software]go/github.com/frain-dev/convoy

HAS_WEAKNESS (1)

[Weakness]Authorization Bypass Through User-Controlled Key

REPORTED_BY (1)

[Source]GitHub Advisory Database

Explore deeper with Ninja Signal's threat intelligence graph

CVE-2026-81505 — Ninja Signal Threat Intelligence | Ninja Signal