MediumPro challengeJavaScriptTypeScript

Fix Missing Function-Level Access Control

Node.jsSecurity

The function below updates a user's benefits start date, taking the target userId directly from the request with no check on who is making the request.

The bug: this is the real behavior of OWASP's NodeGoat (a deliberately-vulnerable Node.js app used for security training) — its benefits-update endpoint lets any logged-in user change any other user's benefits, simply by sending a request with a different userId. There is no check that the requester is an admin or is updating their own record.

Your task: fix solve(requestingUser, targetUserId, newBenefitDate) so the update is only allowed when:

  • the requesting user is an admin, OR
  • the requesting user is updating their own record (requestingUser.id === targetUserId)

Otherwise, return { allowed: false }.

solve({ id: 'u1', isAdmin: false }, 'u1', '2027-01-01')
// → { allowed: true, userId: 'u1', benefitStartDate: '2027-01-01' }  (updating own record)

solve({ id: 'u1', isAdmin: false }, 'u2', '2027-01-01')
// → { allowed: false }  (regular user trying to modify someone else's benefits)

Sample tests

Test #1Regular user updating their own record — allowed
Input: [{"id":"u1","isAdmin":false},"u1","2027-01-01"]
Output: {"userId":"u1","allowed":true,"benefitStartDate":"2027-01-01"}
Test #2Regular user updating someone else's record — blocked
Input: [{"id":"u1","isAdmin":false},"u2","2027-01-01"]
Output: {"allowed":false}
Test #3Admin updating another user's record — allowed
Input: [{"id":"admin1","isAdmin":true},"u2","2027-01-01"]
Output: {"userId":"u2","allowed":true,"benefitStartDate":"2027-01-01"}