Problem
In apps/backend/lambdas/projects/handler.ts only GET /dashboard (L29) calls authenticateRequest. Every other route runs unauthenticated:
POST /projects (L223)
PUT /projects/{id} (L208)
GET /projects (L154), GET /projects/{id} (L198), GET /projects/{id}/members (L131), GET /projects/{id}/donors (L161)
Anyone can read all project financials and create/modify projects without a token. The helpers canCreateProject/canEditProject already exist in projects/auth.ts but are never called.
Mass-assignment (PUT)
PUT /projects/{id} (L211-217) does JSON.parse(event.body) and spreads it straight into .set(body) with no field whitelist or validation. Caller can write any column. Combined with the missing auth, this is unauthenticated arbitrary row mutation.
Fix
- Call
authenticateRequest at the top of the handler (match the pattern in other lambdas).
- Gate
POST with canCreateProject, PUT with canEditProject.
- Gate read routes with
canAccessProject / admin where appropriate.
- Whitelist updatable fields in
PUT and validate via ProjectValidationUtils.
Severity: high.
Problem
In
apps/backend/lambdas/projects/handler.tsonlyGET /dashboard(L29) callsauthenticateRequest. Every other route runs unauthenticated:POST /projects(L223)PUT /projects/{id}(L208)GET /projects(L154),GET /projects/{id}(L198),GET /projects/{id}/members(L131),GET /projects/{id}/donors(L161)Anyone can read all project financials and create/modify projects without a token. The helpers
canCreateProject/canEditProjectalready exist inprojects/auth.tsbut are never called.Mass-assignment (PUT)
PUT /projects/{id}(L211-217) doesJSON.parse(event.body)and spreads it straight into.set(body)with no field whitelist or validation. Caller can write any column. Combined with the missing auth, this is unauthenticated arbitrary row mutation.Fix
authenticateRequestat the top of the handler (match the pattern in other lambdas).POSTwithcanCreateProject,PUTwithcanEditProject.canAccessProject/ admin where appropriate.PUTand validate viaProjectValidationUtils.Severity: high.