Invitation flow validates tenant membership
Why it matters
Invitation flows are a privileged code path: they grant access to a tenant's data before the invitee is a verified member. CWE-330 (Insufficient Randomness) allows token prediction; CWE-613 (Insufficient Session Expiration) keeps compromised tokens valid indefinitely; CWE-285 allows a token issued by Org A to be accepted against Org B. OWASP A07 (Identification & Authentication Failures) covers all three. The real-world consequence is that an attacker who intercepts or guesses an invitation token can join any organization without being explicitly invited.
Severity rationale
High because a guessable or non-expiring invitation token lets an attacker join an arbitrary tenant's workspace without authorization from any member of that tenant.
Remediation
Use cryptographically random tokens, enforce expiration, and validate the token's organization at acceptance time:
// Generation — in src/lib/invitations.ts
const token = crypto.randomUUID() // or randomBytes(32).toString('hex') — 128+ bits of entropy
await db.invitation.create({
data: {
token,
email: invitedEmail,
organizationId: currentOrgId,
expiresAt: new Date(Date.now() + 72 * 60 * 60 * 1000) // 72-hour window
}
})
// Acceptance — validate all constraints atomically
const invite = await db.invitation.findFirst({
where: {
token,
organizationId: params.orgId, // must match the org in the URL
expiresAt: { gt: new Date() }, // must not be expired
acceptedAt: null // must be unused
}
})
if (!invite) return new Response('Invalid or expired invitation', { status: 400 })
if (invite.email.toLowerCase() !== session.user.email.toLowerCase()) {
return new Response('This invitation is for a different email address', { status: 403 })
}
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-330 — Use of Insufficiently Random Values
- cwe · CWE-613 — Insufficient Session Expiration
- cwe · CWE-285 — Improper Authorization
- owasp:2021 · A07 — Identification and Authentication Failures
- soc2:2017 · CC6.2 — User registration, authorization, and access removal
Taxons
History
- 2026-04-18·v1.0.0·Initial import from saas-multi-tenancy·automated
- 2026-07-06·v1.0.1·Add SOC 2 TSC mapping (CC6.2) from the verified compliance crosswalk register (docs/compliance/).·by soc2-mapping-enrichment-ship-2