Platform to build admin panels, internal tools, and dashboards. Integrates with 25+ databases and any API.
fix(security): prevent super user creation race condition (GHSA-9wcp-79g5-5c3c) (#41681)
## Description **TL;DR:** Fix a critical TOCTOU race condition in the `/api/v1/users/super` endpoint that allowed concurrent requests to bypass the single-admin restriction during initial Appsmith setup, enabling multiple unauthorized Instance Administrators. ### Root Cause The `signupAndLoginSuper()` method in `UserSignupCEImpl.java` performed a non-atomic check-then-act sequence: 1. **CHECK:** `isUsersEmpty()` queries MongoDB — returns `true` if no users exist 2. **GAP:** No lock or atomicity guarantee between check and create 3. **ACT:** `signupAndLogin()` creates the user + `makeInstanceAdministrator()` grants admin In the reactive WebFlux environment, concurrent requests all saw an empty database and all proceeded to create admin users. Fixes https://linear.app/appsmith/issue/APP-15067/security-high-super-user-creation-race-condition-allows-multiple Fixes https://github.com/appsmithorg/appsmith/security/advisories/GHSA-9wcp-79g5-5c3c ### Fix Introduces an **atomic sentinel document claim** using MongoDB's `findAndModify` with `upsert=true`: - A lightweight `superUserSetupLock` collection with a fixed `_id` document - `findAndModify` with `upsert` is atomic at the document level — only the first request to upsert wins - All concurrent requests see the existing document and are rejected before user creation - The original `isUsersEmpty()` check is retained as defense-in-depth **Why this approach:** - **Zero race window** — single atomic MongoDB operation - Works on **both standalone MongoDB and replica sets** (no transaction support needed) - No external dependency (Redis, distributed locks) - Minimal code change (7 files, ~200 lines added, 1 line removed) - No regression risk — the sentinel collection is completely isolated from existing data ### Security Impact - **CWE:** CWE-367 (Time-of-Check Time-of-Use Race Condition) - **CVSS 3.1:** AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H — **8.1 (HIGH)** - **Impact:** Authorization bypass allowing persistent backdoor admin accounts ### Files Changed | File | Change | |------|--------| | `CustomUserRepositoryCE.java` | Added `claimSuperUserCreationSlot()` interface method | | `CustomUserRepositoryCEImpl.java` | Implemented atomic sentinel claim via `findAndModify` | | `UserServiceCE.java` | Exposed `claimSuperUserCreationSlot()` in service interface | | `UserServiceCEImpl.java` | Delegated to repository | | `UserSignupCEImpl.java` | Integrated sentinel claim before `isUsersEmpty()` check | | `CustomUserRepositoryCEImplTest.java` | 3 integration tests including concurrent race simulation | | `UserSignupTest.java` | 2 unit tests for rejection paths | ## Automation /ok-to-test tags="@tag.All" ### :mag: Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/23942098312> > Commit: 2f7328a1941ce094a476a2efa014bb4de86201c8 > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=23942098312&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.All` > Spec: > <hr>Fri, 03 Apr 2026 11:03:13 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [x] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Prevented race conditions so only one instance can claim the super-user setup slot and unauthorized simultaneous attempts are rejected. * **Improvements** * Added automatic seeding of a setup lock for existing/upgraded deployments to coordinate startup behavior and ensure cleanup on failure. * **Tests** * Added tests verifying single-winner slot claiming, concurrent claim behavior, and related authorization/failure paths. * **Migrations** * Added a migration to create the sentinel setup lock when appropriate. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
S
subratadeypappu committed
598cbce696754f1f8e9d681d7bb2b33eaedf0dfe
Parent: 6adcbaa
Committed by GitHub <noreply@github.com>
on 4/3/2026, 11:45:17 AM