[Fix] Issue-1101 Security hardening: authz on reward transactions, input validation, regex escaping, secret scrubbing - #1100
Open
devin-ai-integration[bot] wants to merge 1 commit into
Conversation
…extensions, escape regex input, scrub committed secrets Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
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.



Description
Fixes #1101
Security audit fixes for the issue classes requested (secrets, injection, input validation, CORS, debug endpoints, authz, dependencies).
Missing authentication / IDOR (critical) —
GET /api/rewards/transactions/image/:imageIdandGET /api/rewards/transactions/:transactionIdwere unauthenticated, so anyone could enumerate reward ledger entries by ObjectId. Both now require a session, and the single-transaction read additionally requires participation:Committed credentials (critical) —
packages/app/.env.example/.env.dockershipped a real-looking AWS access key + secret, an email-service auth token and a CloudFront key-pair ID;docker-compose.ymlhardcodedadmin:password123. All replaced with placeholders; compose mongo creds are now${MONGO_ROOT_USERNAME:-openlogo}/${MONGO_ROOT_PASSWORD:-local_dev_only_password}(local-throwaway defaults, overridable). The previously committed AWS key, CloudFront key-pair ID and email token should be treated as leaked and rotated — they remain in git history.Unvalidated user input —
extensionflowed from request bodies into S3 object keys ({bucketKey}/{extension}/{name}.{extension}) and DB records with no allowlist. AddedimageExtensionSchema(png|jpg|jpeg|webp|svg, lowercased) and applied it ingetPreSignedController,addCatalogController,updateCatalogControllerandnewLogoRequestController.Regex injection / ReDoS — user input reached mongo
$regexunescaped (notablygetAllImages(search)from the catalog search query). Addedutils/escapeRegExp.jsand applied it inrepositories/images.jsandcontrollers/logo.js(users.jsalready escaped).Cookie hardening — cookie options were duplicated in 8 places and never set
secure. Centralised asgetAuthCookieOptions()inutils/constants.js(httpOnly,sameSite: strict,securein prod) and used from the auth controller and auth middleware.Dependencies —
react-router7.15.1 → ^7.18.2 (unauthenticated DoS, open redirect, RSC CSRF bypass),happy-dom^16 → ^20.8.9 (VM-context escape RCE, dev-only),uuid^9 → ^11.1.1. Not fixed here:vitest/vite/esbuildadvisories need a vite 5 → 7 major bump,image-sizehas no patched release,multer1.x is EOL — all dev/limited-exposure, worth a follow-up.Not vulnerable / no change needed: no SQL (mongoose only); CORS is restricted to
CLIENT_URLrather than*; no debug endpoints, though/docs(Swagger UI) is publicly reachable in every environment and may deserve prod gating.Also
jest.setup.jsdisables mongoose command buffering in tests, so fire-and-forget session writes fail fast instead of logging after the run ends — that was makingpnpm --filter app testexit 1 with all 640 tests passing.What type of PR is this? (Check all applicable)
Screenshots (if applicable)
n/a — backend only.
Checklist
Tests: added 401/403 cases for the two reward endpoints;
pnpm lint,pnpm check,pnpm --filter app test(640),pnpm --filter ui test(566) andpnpm buildall pass.Link to Devin session: https://app.devin.ai/sessions/06593a697bcf4e49bc10ede78584b697
Requested by: @sunnykgupta