Skip to content

fix: secure exception filter, health checks, CSV injection, and transfer approval - #1360

Merged
yusuftomilola merged 1 commit into
DistinctCodes:mainfrom
Hassan-oladipupo:feature/backend-security-improvements
Aug 26, 2026
Merged

fix: secure exception filter, health checks, CSV injection, and transfer approval#1360
yusuftomilola merged 1 commit into
DistinctCodes:mainfrom
Hassan-oladipupo:feature/backend-security-improvements

Conversation

@Hassan-oladipupo

Copy link
Copy Markdown
Contributor

Summary

This PR addresses four backend security and functionality issues:

BE-114: AllExceptionsFilter leaks internal exception messages on 500 responses

  • Non-HttpException errors now return a generic 'Internal server error' message instead of leaking internal details
  • The real error is still logged server-side via Logger.error()

BE-115: Health readiness endpoint hardcodes database status

  • /health/ready now performs an actual database connectivity check via SELECT 1
  • Returns degraded status when database is unreachable

BE-116: CSV export vulnerable to formula/CSV injection

  • escapeCsvField() now neutralizes formula injection by prefixing values starting with =, +, -, @ with a single quote
  • Same protection added to XLSX export cell writes

BE-117: TransfersService.approve() never moves the underlying asset

  • approve() now updates the asset's departmentId to the transfer's toDepartmentId within a transaction
  • Added cancel() and complete() methods for complete transfer lifecycle

Closes #1256
Closes #1257
Closes #1258
Closes #1259

…fer approval

- BE-114: AllExceptionsFilter no longer leaks internal exception messages on 500 responses; non-HttpException errors return generic 'Internal server error'
- BE-115: Health readiness endpoint now performs actual database connectivity check via SELECT 1 instead of hardcoded 'up'
- BE-116: CSV/XLSX export neutralizes formula injection by prefixing values starting with =, +, -, @ with a single quote
- BE-117: TransfersService.approve() now updates the asset's departmentId within a transaction; added cancel() and complete() methods

Closes DistinctCodes#1256
Closes DistinctCodes#1257
Closes DistinctCodes#1258
Closes DistinctCodes#1259
@vercel

vercel Bot commented Aug 25, 2026

Copy link
Copy Markdown

@Hassan-oladipupo is attempting to deploy a commit to the naijabuz's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Aug 25, 2026

Copy link
Copy Markdown

@Hassan-oladipupo 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

@yusuftomilola yusuftomilola left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed. Legitimate security fixes:

  • Exception filter: previously, a non-HttpException error's raw .message was returned directly to the client — a real information-disclosure risk (could leak internal error text/paths). Now only HttpException responses are unwrapped; anything else falls back to the generic 'Internal server error' message. Good fix.
  • CSV/Excel export: both the streaming Excel writer and the CSV escaper now neutralize formula injection by prefixing values starting with =, +, -, @, tab, or CR with a leading quote — the standard mitigation for the classic 'malicious CSV opens as a formula in Excel' attack. Correctly applied in both export paths.
  • Health check: /health/ready now actually pings the database (SELECT 1) instead of hardcoding database: 'up' — this was previously a readiness probe that could never fail.
  • Transfer approve is now wrapped in a real transaction that also moves the asset to the destination department, plus new cancel/complete endpoints with correct status-transition guards (only PENDING can cancel, only APPROVED can complete).

Approving.

@yusuftomilola
yusuftomilola merged commit 595f562 into DistinctCodes:main Aug 26, 2026
6 of 10 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

2 participants