SIGN IN SIGN UP
appsmithorg / appsmith UNCLAIMED

Platform to build admin panels, internal tools, and dashboards. Integrates with 25+ databases and any API.

0 0 68 TypeScript

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