Skip to content

fix(security): scope comment resolve and delete by session — Closes #204 - #209

Merged
harsharajkumar-273 merged 1 commit into
harsharajkumar-273:mainfrom
SakethSumanBathini:fix/comment-scoping-issue-204
Aug 9, 2026
Merged

fix(security): scope comment resolve and delete by session — Closes #204#209
harsharajkumar-273 merged 1 commit into
harsharajkumar-273:mainfrom
SakethSumanBathini:fix/comment-scoping-issue-204

Conversation

@SakethSumanBathini

Copy link
Copy Markdown
Contributor

Closes #204

Two corrections to the issue

Worth stating up front, since neither name in the issue exists in the code:

  • the method is resolveComment, not updateComment
  • the field is author, not authorLogin

The substance holds — both methods key on commentId alone with no scoping filter — but the specifics were wrong and I would rather correct them than let them sit.

The change

async resolveComment(commentId: string, sessionId: string, resolved: boolean) {
  return prisma.comment.update({
    where: { id: commentId, sessionId },
    data: { resolved },
  });
}

deleteComment takes the same treatment.

sessionId is required rather than optional. An optional scoping parameter is one a caller can forget, which reproduces the original defect with extra steps.

Why session and not author

The issue left this open as a product call, and it still is — but the two answers are not equally safe to guess at.

Any route reaching these methods is already behind checkWorkspaceOwner, so the session is the boundary that has actually been authorised. Scoping to it adds a check that cannot be wrong.

Adding an author filter would silently answer a different question: whether a workspace owner may resolve or delete someone else's comment. That is a moderation decision, and encoding it here by accident is exactly the kind of choice that gets discovered later rather than made deliberately.

So this closes the hole that is unambiguous and leaves the one that needs a decision visible — the doc comment says so, rather than leaving the next reader to work out why only half the filter is there.

Filtering in the where clause

Rather than fetching and comparing. A post-fetch check leaks whether the comment exists, and the record is briefly in memory either way. Prisma throws P2025 when nothing matches, which maps cleanly to a 404 covering both "no such comment" and "not in this session".

Verified

  • npx prisma generate then npx tsc --noEmit passes clean, confirming Prisma 7.8 accepts the compound where: { id, sessionId } on both update and delete
  • no callers exist — grep for resolveComment( and deleteComment( outside the definitions returns nothing — so the added parameter breaks nothing
  • backend/dev.db untouched

Related

#207 was the same issue filed twice and is closed as a duplicate of this one.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@SakethSumanBathini, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 55 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3b56df1a-5877-423d-a45d-b72b03464460

📥 Commits

Reviewing files that changed from the base of the PR and between d934ce8 and 6805f16.

📒 Files selected for processing (1)
  • backend/src/repositories/workspace.repository.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@harsharajkumar-273 harsharajkumar-273 added ELUSOC Required Tracking ADVENTURER Intermediate (25 pts) labels Aug 9, 2026
@harsharajkumar-273
harsharajkumar-273 merged commit 07d48f6 into harsharajkumar-273:main Aug 9, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ADVENTURER Intermediate (25 pts) ELUSOC Required Tracking

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Security] Comment update and delete have no ownership filter — unreachable today, an IDOR if wired up

2 participants