Repository navigation
fix(invoice-desk): prevent role escalation through profile updates - #2535
mldangelo-oai wants to merge 2 commits into
Conversation
alandelong-oai
left a comment
There was a problem hiding this comment.
Thanks. Owner-level merge-safety review at c8af00562e8b1c5f78d1359c6ccd0d47b2e60b99: no blocking findings. Profile updates now preserve authorization fields while retaining string display-name editing, and ID-009 is consistently marked as a remediated regression scenario.
Validation: 32 exact-head application/orchestration tests passed on Node 22.23.3; the merged application fixture passed 23 tests, including current main’s request-size check. Restoring the old assignment made all three new profile regressions fail as expected.
The branch has a README-only conflict with current main. Resolve it before merging, retaining the current workflow/artifact documentation and the ID-009 remediation status.
alandelong-oai
left a comment
There was a problem hiding this comment.
No blocking findings in this owner-level merge-safety review. Thanks for preserving the role boundary while retaining display-name editing and for keeping the current Invoice Desk guide intact when merging main.
All 33 application HTTP and orchestration tests passed on Node 22.23.3. Restoring the old profile assignment in a disposable fixture made all three profile regressions fail as expected. The prior README conflict is resolved. No model scan, external deployment or cross-platform runtime test was performed.
The patch restricts profile updates to string display names, closing the role-escalation path.
Static Verification Checks
Profile assignment boundary (Passed) — accounts.mjs updateProfile assigns only string names, preventing request-controlled role or prototype fields from modifying authorization state.
Authenticated request parsing (Passed) — server.mjs readBody parses JSON objects before updateProfile, so escaped property names cannot bypass the fixed assignment.
Administrator authorization remains enforced (Passed) — approveInvoice and updateImportPolicy both call requireAdmin, which reads the stored role that profile updates now preserve.
Display name compatibility (Passed) — views.mjs profilePage submits name through client.js, matching updateProfile's string assignment and preserving publicUser's existing response structure.
Original escalation regression (Passed) — qa/app.test.mjs ID-009 asserts successful name updates retain member roles and both administrator endpoints return forbidden responses.
Alternate payload regression (Passed) — qa/app.test.mjs asserts decoded role, prototype, constructor, and nested payloads preserve account state and cannot enable invoice approval.
Legitimate profile editing (Passed) — qa/app.test.mjs asserts member and administrator name updates preserve identity, empty patches preserve profiles, and administrators retain approval access.
Profile reset behavior (Passed) — qa/app.test.mjs asserts an edited display name returns to its initial value in a fresh application instance.
Finding:
acf_1e90148fba2bf92adc7306bdbb282137Patch:
arp_f93451a5e0c161d55dbcd26fb494ac79Base commit:
4959826a32bbb870457a297aee1e1c37575d5765Patch SHA-256:
7c3ff39cb247e4ce80215907eb464789a4ab925d844d52a753ea8834b9aee1db