Skip to content

JMCP: Papers - jmcp/moderation-abuse-prevention-and-anonymit-5QGr6Yrh#3

Closed
landigf wants to merge 1 commit into
mainfrom
jmcp/moderation-abuse-prevention-and-anonymit-5QGr6Yrh
Closed

JMCP: Papers - jmcp/moderation-abuse-prevention-and-anonymit-5QGr6Yrh#3
landigf wants to merge 1 commit into
mainfrom
jmcp/moderation-abuse-prevention-and-anonymit-5QGr6Yrh

Conversation

@landigf

@landigf landigf commented Mar 23, 2026

Copy link
Copy Markdown
Owner

I now have a complete picture. Here's the review:


Review: Moderation, Abuse Prevention, and Anonymity Safety

Change Summary

This branch bootstraps the full Papers platform — a research-sharing product with feed, papers, conferences with peer review, profiles, daily digest, and opportunities. Key safety-relevant features:

  • Blind mode: Papers can be published with visibilityMode: "blind", which nullifies ownerId and publicAuthorProfile in public-facing serialization (serializePublicPaper). Comments on blind papers also strip authorProfile.
  • Moderation flags: Users can flag content with typed reasons (spam, harassment, misinformation, identity_leak, off_topic, other). Rate-limited to 10 flags/hour/user, with duplicate-per-target prevention.
  • AI safety gate: GrokProvider.assertSafe() blocks blind/private content from being sent to the external LLM.
  • Self-review prevention: Authors cannot review their own conference submissions.
  • Input validation: Zod schemas with length bounds on all user-facing inputs.

Validation Confidence: Medium-High

The core anonymity boundary (blind papers, blind comments, AI gate) is structurally sound. Moderation primitives are present with rate limiting. Demo auth is explicitly scoped and cookie-based.

Risks That Still Remain

Risk Severity Detail
Reviewer identity leak on blind submissions High createPeerReview stores reviewerProfile: viewer.profile and the conference page renders review.reviewerProfile?.displayName. For blind submissions, reviewers are fully identified — this breaks double-blind. The reviewer's identity should be hidden when the submission is blind.
Profile page leaks only filtered by visibilityMode === "public" Medium getProfileByHandle filters papers with paper.visibilityMode === "public", so blind papers won't appear. This is correct but fragile — if a third mode is added, it defaults to visible. Consider an allowlist pattern.
saveInterestAction open redirect Medium redirectTo is taken directly from form data (formData.get("redirectTo")) and passed to redirect() without validation. An attacker could craft a form posting redirectTo=https://evil.com. Same pattern in flagContentAction.
No CSRF protection on demo actions Medium Server actions rely on Next.js built-in origin checking, but the demo cookie auth (papers_demo_viewer) has no additional CSRF token. Acceptable for demo, but needs hardening before production.
No moderation resolution workflow Low Flags are created with status "open" but there is no action or UI to transition flags to "reviewing" or "resolved". Flags accumulate without action.
Comment body not sanitized Low Comment body is rendered as plain text (<p>{comment.body}</p>) in React, so XSS is safe. But there's no content-level moderation (slur filter, PII detection) before storage.
isBlindSafe is always hardcoded true Low Comments set isBlindSafe: true without checking whether the comment text itself contains author-identifying information. The field exists but is never computed.
Demo store TOCTOU Low readDemoState → mutate → writeDemoState has a race condition under concurrent requests. Acceptable for demo, not for production.
Rate limit is in-memory per-read Low The 10-flags/hour check re-reads the JSON store each time, so it works, but a restart/store reset clears the history.

Top Recommendation

The reviewer identity leak on blind submissions is the most critical issue. On the conference page, when a submission has visibilityMode === "blind", the reviewer's full profile is still displayed. This should be masked (e.g., "Reviewer 1", "Reviewer 2") to preserve double-blind integrity. The redirectTo open-redirect pattern should also be fixed before any public deployment.

@landigf

landigf commented Mar 25, 2026

Copy link
Copy Markdown
Owner Author

Closing: will integrate valuable features directly on main to avoid cascade merge conflicts.

@landigf landigf closed this Mar 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant