Listing claim verifies via business contact method, not claimant email alone
Why it matters
Listing claim flows that verify only the claimant's own email let any account take over any business listing by clicking a link sent to themselves. The attack is trivial: submit a claim request for a competitor's listing, confirm the email that arrives in your own inbox, done. OWASP A01 (Broken Access Control), CWE-285 (Improper Authorization), and CWE-287 (Improper Authentication) all apply. The verification must reach the listing's on-file contact, not the claimant.
Severity rationale
Critical because self-email verification allows any user to fraudulently take ownership of any listing, including competitors' businesses.
Remediation
Send the verification token to the listing's contact email on file, not to the claimant. The claimant provides their email so admins can see who is requesting — but the link goes to the business:
// app/api/listings/[id]/claim/route.ts
const listing = await db.listings.findUniqueOrThrow({ where: { id: listingId } })
const token = crypto.randomBytes(32).toString('hex')
await db.claimTokens.create({
data: { listingId, claimantEmail, token, expiresAt: new Date(Date.now() + 48 * 3600_000) }
})
// Email goes to listing.contact_email — NOT to claimantEmail
await sendEmail(listing.contact_email, {
subject: 'Someone is requesting to claim your listing',
body: `Approve at: /listings/${listingId}/verify-claim/${token}`
})
On the verification GET, confirm the token is unexpired and unverified before transferring ownership.
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 User Submissions & Moderation 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-287 — Improper Authentication
- owasp:2021 · A01 — Broken Access Control
Taxons
History
- 2026-04-18·v1.0.0·Initial import from directory-submissions-moderation·automated