Webhook payloads do not include other tenants' data
Why it matters
Outgoing webhooks are an often-overlooked data-egress channel. When a webhook payload is assembled from a broad database query — one not scoped to the triggering tenant — a tenant's webhook endpoint can receive data belonging to a different tenant. CWE-200 (Exposure of Sensitive Information) and OWASP A01 both apply. The business impact is compounded because webhook payloads are delivered to external URLs configured by tenants, meaning a data leak goes directly to a third party outside your control and cannot be retroactively revoked.
Severity rationale
Medium because the data escapes to external systems controlled by tenants, making retrospective containment impossible once a webhook fires with cross-tenant data.
Remediation
Scope all payload-construction queries to the triggering tenant and abort if the resource cannot be confirmed as belonging to that tenant:
async function dispatchWebhook(tenantId: string, event: string, resourceId: string) {
const resource = await db.resource.findFirst({
where: { id: resourceId, organizationId: tenantId } // ownership check in query
})
if (!resource) return // resource doesn't belong to this tenant — abort silently
const subscriptions = await db.webhookSubscriptions.findMany({
where: { organizationId: tenantId, events: { has: event } }
})
// dispatch to subscriptions...
}
Place this pattern in src/lib/webhooks.ts and ensure all include relations on the resource query belong to the same tenant. Never fetch related entities by a bare foreign key without re-validating their organizationId.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Multi-Tenancy Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-285 — Improper Authorization
- cwe · CWE-200 — Exposure of Sensitive Information to an Unauthorized Actor
- owasp:2021 · A01 — Broken Access Control
Taxons
History
- 2026-04-18·v1.0.0·Initial import from saas-multi-tenancy·automated