User Blocking & Safety Mechanisms
Why it matters
Missing user blocking is a critical safety gap under OWASP A01 (Broken Access Control) and CWE-284. Without a blocking system enforced at the query layer, a harassing user remains visible in every surface — profile, feed, search, messaging — regardless of victim intent. This is not merely a UX problem: platforms have faced regulatory scrutiny and civil liability for enabling sustained contact after victims attempted to block. Enforcement must happen at the database level; client-side filtering leaks data before it is suppressed.
Severity rationale
Critical because the absence of query-level block enforcement means harassing users retain full visibility into and interaction capability with victims, creating direct personal safety exposure.
Remediation
Create a Block table with a composite unique index on (blockerId, blockedId) and enforce the block check in every query that returns user content — profile fetches, feed queries, and search results.
// lib/db.ts
export async function getProfile(userId: string, viewerId: string) {
const isBlocked = await db.block.findFirst({
where: {
OR: [
{ blockerId: viewerId, blockedId: userId },
{ blockerId: userId, blockedId: viewerId }
]
}
})
if (isBlocked) return null
return db.user.findUnique({ where: { id: userId } })
}
Apply the same NOT IN (blocked_ids) filter to feed queries and search results. A block check that only covers profiles but not feeds gives a false sense of safety.
Detection
-
ID:
user-blocking-reporting -
Severity:
critical -
What to look for: Enumerate all relevant files and Look for a Block or UserBlock relationship/table in the database schema. Check API endpoints for blocking users (e.g.,
POST /api/users/[id]/block). Verify that blocked users are globally excluded from: profile views, search results, feed visibility, and interaction capability. Look for a "Report User" feature or endpoint as well. -
Pass criteria: At least 1 conforming pattern must exist. A database relationship or table for blocks exists. Blocked users are excluded from profile queries, search, and feed queries. Users cannot interact with blocked accounts (cannot see their posts, cannot follow, cannot message). Report the count of conforming instances found even on pass.
-
Fail criteria: No blocking mechanism exists, or blocked users are visible in search/feed/profile views, or the block status is not checked before allowing interactions.
-
Skip (N/A) when: The platform is internal or has no user safety concerns.
-
Detail on fail:
"No user blocking table found in schema"or"Block relationship exists but profile queries do not check block status — blocked users are still visible" -
Remediation: Implement a blocks system and enforce it across all queries:
// Prisma schema model Block { id String @id @default(cuid()) blockerId String blockedId String blocker User @relation(name: "blocker", fields: [blockerId], references: [id], onDelete: Cascade) blocked User @relation(name: "blocked", fields: [blockedId], references: [id], onDelete: Cascade) createdAt DateTime @default(now()) @@unique([blockerId, blockedId]) } // lib/db.ts - exclude blocks from all queries export async function getProfile(userId: string, viewerId: string) { const isBlocked = await db.block.findFirst({ where: { OR: [ { blockerId: viewerId, blockedId: userId }, { blockerId: userId, blockedId: viewerId } ] } }) if (isBlocked) return null return db.user.findUnique({ where: { id: userId } }) } // API route for blocking export async function POST(req: Request, { params }) { const { blockUserId } = await req.json() const userId = getCurrentUserId() // From auth await db.block.create({ data: { blockerId: userId, blockedId: blockUserId } }) return Response.json({ success: true }) }
External references
- cwe · CWE-284 — Improper Access Control
- owasp:2021 · A01 — Broken Access Control
Taxons
History
- 2026-04-18·v1.0.0·Initial import from community-social-engagement·automated