fix: secure exception filter, health checks, CSV injection, and transfer approval - #1360
Merged
yusuftomilola merged 1 commit intoAug 26, 2026
Conversation
…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
|
@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. |
|
@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! 🚀 |
yusuftomilola
approved these changes
Aug 26, 2026
yusuftomilola
left a comment
Collaborator
There was a problem hiding this comment.
Reviewed. Legitimate security fixes:
- Exception filter: previously, a non-HttpException error's raw
.messagewas 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/readynow actually pings the database (SELECT 1) instead of hardcodingdatabase: '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.
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR addresses four backend security and functionality issues:
BE-114: AllExceptionsFilter leaks internal exception messages on 500 responses
BE-115: Health readiness endpoint hardcodes database status
/health/readynow performs an actual database connectivity check viaSELECT 1BE-116: CSV export vulnerable to formula/CSV injection
escapeCsvField()now neutralizes formula injection by prefixing values starting with=,+,-,@with a single quoteBE-117: TransfersService.approve() never moves the underlying asset
approve()now updates the asset'sdepartmentIdto the transfer'stoDepartmentIdwithin a transactioncancel()andcomplete()methods for complete transfer lifecycleCloses #1256
Closes #1257
Closes #1258
Closes #1259