Profanity or objectionable content filter on user input
Why it matters
Apple's guideline 1.2 requires apps accepting user-generated text to filter objectionable content before it is stored and shown to others. Storing post or comment text directly to the database with no filtering (CWE-20, OWASP input validation) means a reviewer can post profanity or offensive content in your app and immediately see it appear — a scenario that results in rejection. Client-side filtering alone is insufficient because it is trivially bypassed via direct API calls. The combination of server-side filtering and the reporting mechanism (ab-000498) is the minimum acceptable moderation stack for any UGC platform.
Severity rationale
Medium because unfiltered UGC submission directly violates Apple guideline 1.2 and any reviewer can verify the failure in seconds by typing into a post field.
Remediation
Add server-side content filtering to every UGC submission route before writing to the database.
// src/app/api/posts/route.ts
import Filter from 'bad-words';
const filter = new Filter();
export async function POST(req: Request) {
const { text } = await req.json();
if (filter.isProfane(text)) {
return Response.json({ error: 'Content violates community guidelines' }, { status: 400 });
}
// proceed to store
}
For image content, integrate AWS Rekognition or Google Vision Safe Search. For higher-volume text needs, the OpenAI Moderation API is free and covers hate speech, self-harm, and sexual content categories that bad-words misses. Client-side filtering is a UX nicety, not a substitute for server-side enforcement.
Detection
- ID:
objectionable-content-filter - Severity:
medium - What to look for: Count all relevant instances and enumerate each. Search for content filtering on text input: libraries like
bad-words,profanity-filter,leo-profanity, or custom filter implementations with word lists. Look for API-side filtering in server routes that accept UGC (search forfilter,sanitize,moderate,checkcalls before storing text). Check if text input components havemaxLengthlimits. Look for third-party moderation API calls at post/submit time (OpenAI Moderation API, Google Perspective API, Hive Moderation). - Pass criteria: Text submitted as UGC goes through some form of content filtering before being stored and shown to other users — either client-side or server-side. At least 1 implementation must be verified.
- Fail criteria: UGC text is accepted and stored with no filtering, sanitization, or moderation checks of any kind.
- Skip (N/A) when: App has no user-generated text content (no posts, comments, messages, reviews, or bio fields visible to others).
- Detail on fail:
"Post submission in src/api/posts.ts stores text directly to database with no content filtering" - Remediation: Filtering objectionable content is a requirement for apps with UGC per Apple guideline 1.2.
- Add server-side content filtering on all UGC submission endpoints:
import Filter from 'bad-words'; const filter = new Filter(); if (filter.isProfane(postText)) { return res.status(400).json({ error: 'Content violates community guidelines' }); } - For image content, use AWS Rekognition or Google Vision Safe Search
- For more sophisticated needs, use OpenAI Moderation API (free) or Perspective API
- Client-side filtering alone is not sufficient — always validate server-side
- Add server-side content filtering on all UGC submission endpoints:
External references
- cwe · CWE-20 — Improper Input Validation
- external · apple-guideline-1.2-ugc-filter — Apple App Store Review Guideline 1.2 — User-Generated Content (objectionable content filter)
Taxons
History
- 2026-04-18·v1.0.0·Initial import from app-store-review-blockers·automated