Skip to content

fix: prevent information disclosure via error messages in controllers (#162) - #171

Merged
DioChuks merged 2 commits into
BuidlZone-Labs:mainfrom
Yerimahjr:fix/error-info-disclosure-162
Jul 29, 2026
Merged

fix: prevent information disclosure via error messages in controllers (#162)#171
DioChuks merged 2 commits into
BuidlZone-Labs:mainfrom
Yerimahjr:fix/error-info-disclosure-162

Conversation

@Yerimahjr

@Yerimahjr Yerimahjr commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #162. Controllers across the app were leaking raw internal error.message text directly to clients on 500 responses (and in some cases even on non-500 responses), exposing exception details, stack-adjacent info, and other internals that shouldn't reach an end user.

What was already there

This repo already had solid infrastructure for this: a centralized globalErrorHandler (handles ZodError formatting, AppError subclasses safely, and masks generic 500s) and a full AppError class taxonomy (NotFoundError, ValidationError, ConflictError, etc.). The actual gap was that controllers weren't using it — they were catching errors and responding directly instead of calling next(error).

What changed

14 controllers fixed, in two passes:

  • Bare/generic leaks (login, otp, resendotp, zkemail, verify, organizer-balance, queue-monitor, verify-attend) — straightforward: replaced res.status(500).json({ message: error.message }) with next(error).
  • Mixed-logic controllers (event-ticket, media, message-center, news, ticket-order, waitlist) — more care taken here: legitimate, intentional status-code branches (e.g. mapping a known "News article not found" message to 404, or a Zod validation failure to 400) were left untouched, since those aren't the vulnerability. Only the generic catch-all 500 fallback in each was replaced with next(error).

Also fixed a related correctness bug found along the way in news.controller.ts's updateNews: it had no fallback branch at all, so an unexpected error would leave the request hanging with no response.

Testing

Updated 3 test files (event-ticket, message-center, news .controller.test.ts) that were asserting the old raw-500 behavior directly — they now assert next was called with an Error instead.

Full suite: 276/276 tests passing, 36/36 suites, zero regressions.

Summary by CodeRabbit

  • Bug Fixes

    • Improved error handling across event tickets, authentication, media, messaging, news, orders, waitlists, and related services.
    • Server-side failures are now handled consistently, improving error responses and reducing inconsistent endpoint behavior.
  • Tests

    • Updated controller tests to verify centralized error handling and ensure failed requests do not send duplicate responses.

@drips-wave

drips-wave Bot commented Jul 28, 2026

Copy link
Copy Markdown

@Yerimahjr Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

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

Next review available in: 52 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 91eb3fb1-122a-43e6-85be-844778e44586

📥 Commits

Reviewing files that changed from the base of the PR and between d2447a0 and a8e5779.

📒 Files selected for processing (4)
  • src/controllers/event-ticket.controller.ts
  • src/controllers/media.controller.ts
  • src/controllers/message-center.controller.ts
  • src/controllers/verify.controller.ts
📝 Walkthrough

Walkthrough

Controllers across the application now pass unhandled exceptions to Express error middleware via next(error) instead of returning local 500 responses. Validation and typed domain-error responses remain in selected handlers, and affected tests now verify middleware propagation.

Changes

Controller error propagation

Layer / File(s) Summary
Ticket and media controller propagation
src/controllers/event-ticket.controller.ts, src/controllers/media.controller.ts
Event-ticket and media handlers accept next and forward caught server errors instead of returning local 500 responses.
Messaging and news controller propagation
src/controllers/message-center.controller.ts, src/controllers/news.controller.ts
Message and news handlers preserve typed responses while forwarding unmatched errors through next(error).
Authentication and operations propagation
src/controllers/login.controller.ts, src/controllers/organizer-balance.controller.ts, src/controllers/otp.controller.ts, src/controllers/queue-monitor.controller.ts, src/controllers/resendotp.controller.ts, src/controllers/verify*.controller.ts, src/controllers/zkemail.controller.ts
Authentication, verification, queue, balance, resend, and zk-email handlers now delegate fallback errors to Express middleware.
Order and waitlist propagation
src/controllers/ticket-order.controller.ts, src/controllers/waitlist.controller.ts
Order and waitlist handlers forward unhandled failures through next(error) while retaining existing application-error branches.
Error propagation test expectations
tests/event-ticket.controller.test.ts, tests/message-center.controller.test.ts, tests/news.controller.test.ts
Tests now expect next(error) and no local response for selected service failures.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Concise and specific; it matches the controller error-message masking change.
Linked Issues check ✅ Passed Controllers now delegate unexpected errors with next(error), while safe AppError and validation paths remain preserved in the updated tests.
Out of Scope Changes check ✅ Passed Changes stay focused on controller error forwarding and matching tests; no unrelated functional scope is evident.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/event-ticket.controller.test.ts (1)

152-166: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Strengthen all error-propagation assertions.

These tests currently accept any Error and only forbid res.status; they would pass if the controller replaced the original error or responded directly via res.json.

  • tests/event-ticket.controller.test.ts#L152-L166: capture the service rejection, assert next is called once with that exact error, and verify both res.status and res.json are unused.
  • tests/message-center.controller.test.ts#L157-L170: apply the same exact-error and no-response assertions to createMessage.
  • tests/message-center.controller.test.ts#L240-L256: apply the same assertions to getScheduledMessages.
  • tests/news.controller.test.ts#L99-L111: apply the same assertions to incrementReadCount.
  • tests/news.controller.test.ts#L171-L181: apply the same assertions to getSingleNewsBySlug.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/event-ticket.controller.test.ts` around lines 152 - 166, Strengthen the
unexpected-error tests by storing each mocked service rejection in a shared
error instance, asserting the controller calls next exactly once with that same
instance, and verifying neither res.status nor res.json is called. Apply this to
tests/event-ticket.controller.test.ts:152-166 for searchEventTickets,
tests/message-center.controller.test.ts:157-170 for createMessage and :240-256
for getScheduledMessages, and tests/news.controller.test.ts:99-111 for
incrementReadCount and :171-181 for getSingleNewsBySlug.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/controllers/ticket-order.controller.ts`:
- Around line 79-80: Restore the corrupted comments in the verify-payment flow,
including the comment at the payment verification section and the related
comments near the ticket issuance and completion sections. Replace the mojibake
text with the intended readable Unicode punctuation and wording, without
changing executable code.

---

Nitpick comments:
In `@tests/event-ticket.controller.test.ts`:
- Around line 152-166: Strengthen the unexpected-error tests by storing each
mocked service rejection in a shared error instance, asserting the controller
calls next exactly once with that same instance, and verifying neither
res.status nor res.json is called. Apply this to
tests/event-ticket.controller.test.ts:152-166 for searchEventTickets,
tests/message-center.controller.test.ts:157-170 for createMessage and :240-256
for getScheduledMessages, and tests/news.controller.test.ts:99-111 for
incrementReadCount and :171-181 for getSingleNewsBySlug.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d5b33485-f52e-4010-9728-ebaad99f2037

📥 Commits

Reviewing files that changed from the base of the PR and between 4c17c60 and d2447a0.

📒 Files selected for processing (17)
  • src/controllers/event-ticket.controller.ts
  • src/controllers/login.controller.ts
  • src/controllers/media.controller.ts
  • src/controllers/message-center.controller.ts
  • src/controllers/news.controller.ts
  • src/controllers/organizer-balance.controller.ts
  • src/controllers/otp.controller.ts
  • src/controllers/queue-monitor.controller.ts
  • src/controllers/resendotp.controller.ts
  • src/controllers/ticket-order.controller.ts
  • src/controllers/verify-attend.controller.ts
  • src/controllers/verify.controller.ts
  • src/controllers/waitlist.controller.ts
  • src/controllers/zkemail.controller.ts
  • tests/event-ticket.controller.test.ts
  • tests/message-center.controller.test.ts
  • tests/news.controller.test.ts

Comment thread src/controllers/ticket-order.controller.ts

@DioChuks DioChuks left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM! 🚀
Great Work!
Thanks for your contribution!

@DioChuks
DioChuks merged commit 4f10ec5 into BuidlZone-Labs:main Jul 29, 2026
5 checks passed
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.

Information Disclosure via Error Messages in Controllers

2 participants