From 0b8c4dffde5f91adcd8079f684e3220a07b5b962 Mon Sep 17 00:00:00 2001 From: ldsgroups225 <173761647+ldsgroups225@users.noreply.github.com> Date: Wed, 1 Apr 2026 23:29:40 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[CRITICAL]?= =?UTF-8?q?=20Fix=20privilege=20escalation=20vulnerability=20in=20updateRo?= =?UTF-8?q?le?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .jules/sentinel.md | 4 ++++ packages/data-ops/src/queries/school-admin/roles.ts | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/.jules/sentinel.md b/.jules/sentinel.md index 0ae11818..bb15b6d6 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -15,3 +15,7 @@ **Vulnerability:** Internal system error messages (`error.originalError.message`) were leaked in API 500 error responses in `apps/data-service/src/hono/routes/demo.ts`. **Learning:** Returning unhandled database or internal system errors directly to the client can leak sensitive information about the backend architecture. **Prevention:** Always sanitize error messages returned in JSON responses. Log detailed errors on the server, but return generic messages (e.g. `error.message` of a custom domain error rather than the original system error) to the client. +## 2025-03-18 - [Fix Privilege Escalation Vulnerability in updateRole] +**Vulnerability:** Tenants can modify system roles because `updateRole` lacks an `isSystemRole` check. +**Learning:** System roles (roles with `isSystemRole: true`) must be protected from modification by individual tenants to prevent privilege escalation. +**Prevention:** Always check `isSystemRole` and throw a validation error before updating or deleting a role. diff --git a/packages/data-ops/src/queries/school-admin/roles.ts b/packages/data-ops/src/queries/school-admin/roles.ts index 4d777d42..a1bf885b 100644 --- a/packages/data-ops/src/queries/school-admin/roles.ts +++ b/packages/data-ops/src/queries/school-admin/roles.ts @@ -124,6 +124,12 @@ export function updateRole( throw new DatabaseError('NOT_FOUND', SCHOOL_ERRORS.ROLE_NOT_FOUND) } + const role = roleResult.value + + if (role.isSystemRole) { + throw new DatabaseError('VALIDATION_ERROR', 'Cannot modify system roles') + } + const [updated] = await db .update(roles) .set({