Review text content cannot be edited after submission without moderation
Why it matters
An edit route that updates review text without resetting status to 'pending' creates a post-approval backdoor: a user submits a clean review, it passes moderation, then they edit it to inject harmful content that immediately goes live because the approved status is preserved. CWE-284 (Improper Access Control) applies — the user gains a privilege (bypassing moderation) they were not supposed to retain after the initial approval. This also means edit protection is inseparable from ecommerce-reviews.moderation-trust.moderation-enforced: if moderation exists, every write path to review content must re-enter it.
Severity rationale
High because a post-approval edit bypass gives any authenticated user a reliable path to publish arbitrary content to live product pages without moderation.
Remediation
Either remove edit functionality entirely, or force re-approval on every text edit in api/reviews/[id]/route.ts.
// api/reviews/[id]/route.ts — PATCH handler
export async function PATCH(req: Request, { params }: { params: { id: string } }) {
const { text } = await req.json()
const session = await getServerSession()
if (!session) return Response.json({ error: 'Unauthorized' }, { status: 401 })
// Verify ownership
const review = await db.reviews.findUnique({ where: { id: params.id } })
if (review?.user_id !== session.user.id) return Response.json({ error: 'Forbidden' }, { status: 403 })
await db.reviews.update({
where: { id: params.id },
data: {
text,
status: 'pending' // Always re-queue; never preserve 'approved' after content change
}
})
return Response.json({ status: 'pending_review' })
}
Any edit pathway that touches text or rating must include status: 'pending' in the same UPDATE statement.
Detection
-
ID:
edit-protection -
Severity:
high -
What to look for: List all API routes and form components that handle review editing (PUT/PATCH endpoints for reviews, edit buttons in review display). For each edit pathway, classify whether the handler resets status to
pendingafter an edit operation. Count edit pathways that bypass moderation. -
Pass criteria: Either no edit functionality exists for submitted reviews (no edit routes or UI), or every edit pathway (at least 1 API route and 1 UI trigger) resets the review status to
pendingfor re-approval before the edited content becomes publicly visible. -
Fail criteria: At least 1 edit pathway allows authors to modify review content that is auto-published without re-entering the moderation queue. Must not pass when an edit route exists that updates
textwithout also settingstatus = 'pending'. -
Skip (N/A) when: The moderation-enforced check already failed or was skipped — if reviews are not moderated at all, edit protection is moot.
-
Detail on fail:
"1 edit pathway found (PUT /api/reviews/:id). Handler updates text and rating but does not reset status to pending. Edited reviews bypass moderation." -
Remediation: Either remove edit functionality or require re-approval on edit in
api/reviews/[id]/route.ts:// Option 1: Disable editing // Don't create an edit form/route // Option 2: Require re-approval on edit // POST /api/reviews/:id/edit await db.reviews.update({ where: { id: reviewId }, data: { text: newText, status: 'pending' // Re-queue for review } })
External references
- cwe · CWE-284 — Improper Access Control
Taxons
History
- 2026-04-18·v1.0.0·Initial import from ecommerce-reviews·automated