Findings from a security audit of the backend (see PR #1100):
- Missing authentication / IDOR (critical):
GET /api/rewards/transactions/image/:imageId and GET /api/rewards/transactions/:transactionId are unauthenticated, allowing anyone to enumerate reward ledger entries by ObjectId.
- Committed credentials (critical):
packages/app/.env.example and .env.docker contain real-looking AWS access key/secret, a CloudFront key-pair ID and an email-service auth token; docker-compose.yml hardcodes mongo root credentials. These need scrubbing and rotation.
- Unvalidated input (high):
extension flows from request bodies into S3 object keys and DB records with no allowlist.
- Regex injection / ReDoS (high): user-supplied search terms reach mongo
$regex unescaped.
- Cookie hardening (medium): auth cookie options are duplicated across the codebase and never set
secure.
- Vulnerable dependencies (medium):
react-router, happy-dom, uuid have patched releases; vite/vitest/esbuild, image-size and multer 1.x need follow-up.
- Public Swagger UI (low/medium):
/docs is reachable in every environment.
No SQL injection surface (mongoose only) and CORS is correctly restricted to CLIENT_URL.
Findings from a security audit of the backend (see PR #1100):
GET /api/rewards/transactions/image/:imageIdandGET /api/rewards/transactions/:transactionIdare unauthenticated, allowing anyone to enumerate reward ledger entries by ObjectId.packages/app/.env.exampleand.env.dockercontain real-looking AWS access key/secret, a CloudFront key-pair ID and an email-service auth token;docker-compose.ymlhardcodes mongo root credentials. These need scrubbing and rotation.extensionflows from request bodies into S3 object keys and DB records with no allowlist.$regexunescaped.secure.react-router,happy-dom,uuidhave patched releases;vite/vitest/esbuild,image-sizeandmulter1.x need follow-up./docsis reachable in every environment.No SQL injection surface (mongoose only) and CORS is correctly restricted to
CLIENT_URL.