Without enforceable bans, repeat violators face no real consequence — they continue posting after receiving warnings, and the moderation system becomes a signal they can ignore. OWASP A01:2021 (Broken Access Control, CWE-285) applies when ban records exist in the database but the enforcement check is missing from content-creation and interaction endpoints. A ban table with no WHERE clause enforcement is a paper ban: the record exists, but the behavior continues. Communities with no ban enforcement experience higher recidivism from bad actors who quickly learn there is no real cost to violations.
High because without enforcement checks at content-creation endpoints, banned users can immediately resume posting, rendering all prior moderation actions ineffective.
Check ban status at the start of every content-creation and interaction handler. Invalidate sessions on ban to force immediate logout:
async function assertNotBanned(userId) {
const user = await db.users.findOneById(userId);
if (!user.banned) return;
// Auto-lift expired temporary bans
if (user.bannedUntil && user.bannedUntil < new Date()) {
await db.users.update(userId, { banned: false, bannedUntil: null });
return;
}
throw Object.assign(new Error('Account is banned'), { status: 403 });
}
// Apply at every post/comment/message endpoint
app.post('/api/posts', authenticate, async (req, res) => {
await assertNotBanned(req.user.id);
// ... create post
});
Store bans with at minimum: userId, reason, bannedAt, bannedBy, and optional bannedUntil for temporary suspensions.
ID: community-moderation-safety.report-enforcement.user-bans
Severity: high
What to look for: Check if moderators can ban or suspend users. Look for a user ban/suspension table or feature. Verify that banned users cannot post, comment, or create new accounts (or face friction).
Pass criteria: Moderators can ban/suspend users for policy violations through at least 1 explicit mechanism (admin UI, CLI, or API endpoint). Enumerate all content-creation and interaction endpoints and confirm each checks the ban status before allowing action. Banned users cannot post new content or interact with the platform. A ban record is maintained with at least 3 fields: user ID, reason, and timestamp.
Fail criteria: No user ban mechanism exists, or banned users can still post by creating new accounts. A ban table with no enforcement check in the post-creation path does not count as pass.
Skip (N/A) when: Never — enforcement against repeat violators is essential.
Detail on fail: "No ban mechanism exists. Abusive users cannot be removed from the platform."
Remediation: Implement user bans that prevent banned users from posting or interacting:
// Moderator endpoint to ban user
app.patch('/api/admin/users/:id/ban', verifyModerator, async (req, res) => {
const { reason, duration } = req.body;
// Calculate ban expiration (null = permanent)
const bannedUntil = duration ? new Date(Date.now() + duration) : null;
// Update user record
await db.users.updateOne(
{ _id: req.params.id },
{
banned: true,
bannedReason: reason,
bannedUntil,
bannedAt: new Date(),
bannedBy: req.user.id
}
);
// Invalidate all active sessions to force logout
await db.sessions.deleteMany({ userId: req.params.id });
res.status(200).json({ success: true, message: 'User banned' });
});
// Check ban status before all actions
async function checkUserBan(userId) {
const user = await db.users.findOne({ _id: userId });
if (user.banned) {
// Check if ban is temporary and expired
if (user.bannedUntil && user.bannedUntil < new Date()) {
// Unban user automatically
await db.users.updateOne(
{ _id: userId },
{ banned: false, bannedUntil: null }
);
} else {
throw new Error('User is banned');
}
}
}
// Middleware to enforce ban check on posting
app.post('/api/posts', authenticate, async (req, res) => {
try {
await checkUserBan(req.user.id);
} catch (err) {
return res.status(403).json({ error: err.message });
}
// ... create post
});