Spam patterns and duplicate content are detected
Why it matters
Without spam detection, a single automated account can flood a community feed with duplicate or rapid-fire posts, drowning legitimate content and degrading the user experience to the point where real users leave. This is a CWE-770 (Allocation of Resources Without Limits) failure: uncapped post creation burns database storage and CDN bandwidth at attacker-controlled rates. Beyond quality, spam floods can mask coordinated manipulation campaigns — link farms, referral abuse, or coordinated inauthentic behavior — that are invisible without rate tracking.
Severity rationale
Low because spam degrades platform quality and inflates infrastructure costs but does not expose user data or enable direct account compromise.
Remediation
Implement per-user rate limiting and content-hash deduplication on all post/comment submission handlers. In src/middleware/rateLimiter.ts:
import rateLimit from 'express-rate-limit';
export const postLimiter = rateLimit({
windowMs: 5 * 60 * 1000, // 5 minutes
max: 5,
keyGenerator: (req) => req.user.id,
message: 'Too many posts. Please wait before posting again.'
});
Pair rate limiting with a content-hash check: compute sha256(content) per user and reject exact duplicates submitted within the last hour. Reject at the API level before writing to the database.
Detection
-
ID:
spam-detection -
Severity:
low -
What to look for: Check for logic that detects spam: rapid repeated posting, duplicate content, suspicious patterns (many links, excessive hashtags), or third-party spam detection services. Look for rate limiting on post/comment submissions, or duplicate content comparison before save.
-
Pass criteria: The system detects and handles spam: either rejects rapid postings from the same user, deduplicates identical content, or uses a third-party spam detection service. Count all post/comment submission handlers and verify that at least 1 spam-detection mechanism (rate limit, dedup, or spam API) is applied. Actions are taken before or immediately after content creation. Report the ratio of spam-protected endpoints to total submission endpoints even on pass.
-
Fail criteria: No spam detection is implemented. Users can flood the platform with duplicate or rapid-fire content. A TODO comment or disabled spam check does not count as pass.
-
Skip (N/A) when: Platform has <500 active users AND uses manual-only moderation.
-
Detail on fail:
"No spam detection implemented. A user can post identical content repeatedly or flood the platform with rapid postings." -
Remediation: Implement rate limiting and duplicate detection on post submissions:
import { rateLimit } from 'express-rate-limit'; // Rate limiting: 5 posts per 5 minutes per user const postLimiter = rateLimit({ windowMs: 5 * 60 * 1000, max: 5, keyGenerator: (req) => req.user.id, message: 'Too many posts. Please wait before posting again.' }); app.post('/api/posts', postLimiter, async (req, res) => { const { content } = req.body; const userId = req.user.id; // Check for duplicate content in the last hour const recentPost = await db.posts.findOne({ content, userId, createdAt: { $gte: new Date(Date.now() - 3600000) } }); if (recentPost) { return res.status(400).json({ error: 'You already posted this content recently' }); } // Check for similar content using simple hash-based deduplication const contentHash = require('crypto').createHash('md5').update(content).digest('hex'); const similar = await db.postHashes.findOne({ hash: contentHash, userId }); if (similar) { return res.status(400).json({ error: 'Similar content already posted' }); } // Save post const post = await db.posts.create({ content, userId, createdAt: new Date() }); await db.postHashes.create({ hash: contentHash, userId, postId: post.id }); res.status(201).json(post); });Reject posts that exceed the rate limit and flag exact duplicates.
External references
- cwe · CWE-770 — Allocation of Resources Without Limits or Throttling
Taxons
History
- 2026-04-18·v1.0.0·Initial import from community-moderation-safety·automated