Skip to content

Fix: Resolve IDOR on Reply Creation API#279

Merged
knoxiboy merged 5 commits into
knoxiboy:mainfrom
riddhima25bet10005-a11y:fix-267
May 26, 2026
Merged

Fix: Resolve IDOR on Reply Creation API#279
knoxiboy merged 5 commits into
knoxiboy:mainfrom
riddhima25bet10005-a11y:fix-267

Conversation

@riddhima25bet10005-a11y
Copy link
Copy Markdown
Contributor

Description

Fixes an Insecure Direct Object Reference (IDOR) vulnerability in the \POST /api/replies\ endpoint where an unauthenticated or unauthorized user could post replies to doubts belonging to classrooms they were not enrolled in.

The endpoint now correctly validates the classroom membership of the requesting user when creating a reply on a classroom-scoped doubt.

Fixes #267

Changes Made

  • Added classroom membership validation check in \�pp/api/replies/route.ts\ POST method
  • Included \membershipsTable\ in the Drizzle schema imports for the file

Checklist

  • I have tested my changes locally
  • I have followed the GSSoC '26 contribution guidelines
  • The code is clean and well-documented

@vercel
Copy link
Copy Markdown

vercel Bot commented May 24, 2026

@riddhima25bet10005-a11y is attempting to deploy a commit to the Karan Mani Tripathi 's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions Bot added size/size/s gssoc'26 GSSoC program issue type:bug Bug fix labels May 24, 2026
@github-actions github-actions Bot requested a review from knoxiboy May 24, 2026 13:50
@riddhima25bet10005-a11y
Copy link
Copy Markdown
Contributor Author

Hi @knoxiboy
Kindly review and approve.

@knoxiboy knoxiboy added level:advanced Advanced level task and removed gssoc labels May 24, 2026
@riddhima25bet10005-a11y
Copy link
Copy Markdown
Contributor Author

@knoxiboy reviewed?

Copy link
Copy Markdown
Owner

@knoxiboy knoxiboy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review: Thank you for starring the repository! The PR is approved.

Note: This PR currently has merge conflicts with the main branch. Please resolve the merge conflicts so we can complete the merge!

@riddhima25bet10005-a11y
Copy link
Copy Markdown
Contributor Author

Hey @knoxiboy
The conflicts in the base branch are resolved.
Kindly review and merge.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to fix an IDOR vulnerability in POST /api/replies by ensuring the requester is authorized (classroom member) before allowing reply creation for classroom-scoped doubts.

Changes:

  • Added a classroom membership check against membershipsTable when creating a reply for a doubt with a classroomId.
  • Added a 404 response when the target doubt does not exist.
  • Updated the footer to include additional “Resources” links (not mentioned in the PR description).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
app/api/replies/route.ts Adds doubt existence check and classroom membership authorization gate for reply creation.
components/Footer.tsx Adds new footer navigation links and refactors link rendering logic.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread components/Footer.tsx
Comment on lines 26 to 33
{
title: "Resources",
links: [
{ label: "Public Doubts", href: "/public-rooms" },
{ label: "Bookmarks", href: "/bookmarks" },
{ label: "Privacy Policy", href: "/privacy-policy" },
{ label: "Terms of Service", href: "/terms-of-service" },
{ label: "About", href: "/about" },
Comment thread app/api/replies/route.ts
import { repliesTable, doubtsTable, classroomsTable, replyLikesTable, usersTable, membershipsTable, notificationsTable } from "@/configs/schema";
import { eq, asc, sql, and } from "drizzle-orm";
import { NextResponse } from "next/server";
import { auth, currentUser } from "@clerk/nextjs/server";
Comment thread app/api/replies/route.ts
if (doubt.classroomId) {
const [membership] = await db.select().from(membershipsTable).where(
and(eq(membershipsTable.userEmail, email), eq(membershipsTable.classroomId, doubt.classroomId))
);
Comment thread app/api/replies/route.ts
Comment on lines 98 to +121
// 1. AI Moderation Check
if (content) {
const moderation = await moderateContent(content);
const violationError = await handleModerationViolation(email, content, moderation);
if (violationError) {
return NextResponse.json({ error: violationError }, { status: 400 });
}
}

// Security: Check if it's a teacher doubt
// Security: Check if it's a teacher doubt and verify classroom membership
const [doubt] = await db.select().from(doubtsTable).where(eq(doubtsTable.id, doubtId));
if (doubt?.type === 'teacher') {

if (!doubt) {
return NextResponse.json({ error: "Doubt not found" }, { status: 404 });
}

if (doubt.classroomId) {
const [membership] = await db.select().from(membershipsTable).where(
and(eq(membershipsTable.userEmail, email), eq(membershipsTable.classroomId, doubt.classroomId))
);
if (!membership) {
return NextResponse.json({ error: "Access denied to this classroom" }, { status: 403 });
}
}
Comment thread app/api/replies/route.ts
Comment on lines +114 to +121
if (doubt.classroomId) {
const [membership] = await db.select().from(membershipsTable).where(
and(eq(membershipsTable.userEmail, email), eq(membershipsTable.classroomId, doubt.classroomId))
);
if (!membership) {
return NextResponse.json({ error: "Access denied to this classroom" }, { status: 403 });
}
}
@knoxiboy
Copy link
Copy Markdown
Owner

Hi there! 👋 Thanks for your contribution to DoubtDesk.

It looks like there are currently some merge conflicts between your branch and the main branch. Could you please pull the latest changes from main, resolve the conflicts, and push the updates to this branch?

Once the conflicts are resolved and the PR is clean, we'll be able to merge it!

Signed-off-by: Riddhima Saluja <riddhima.25bet10005@vitbhopal.ac.in>
…s on fix-267 branch

Signed-off-by: Riddhima Saluja <riddhima.25bet10005@vitbhopal.ac.in>
@riddhima25bet10005-a11y
Copy link
Copy Markdown
Contributor Author

@knoxiboy
Now there are no conflicts with base branch from my side.
Kindly confirm.

# Conflicts:
#	app/api/replies/route.ts
@github-actions github-actions Bot added size/s and removed size/m labels May 26, 2026
@github-actions github-actions Bot added size/m and removed size/s labels May 26, 2026
Copy link
Copy Markdown
Owner

@knoxiboy knoxiboy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code changes look excellent. Thank you for your contribution to DoubtDesk! 🎉

@knoxiboy knoxiboy merged commit e300163 into knoxiboy:main May 26, 2026
3 of 4 checks passed
@github-actions github-actions Bot added gssoc:approved Approved for GSSoC mentor:knoxiboy Reviewed by mentor knoxiboy quality:clean Clean code quality and removed size/m labels May 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gssoc:approved Approved for GSSoC gssoc'26 GSSoC program issue level:advanced Advanced level task mentor:knoxiboy Reviewed by mentor knoxiboy quality:clean Clean code quality type:bug Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

IDOR on Reply Creation (POST /api/replies)

3 participants