nginx ignition has Unauthenticated Admin Account Creation via Onboarding Race Condition
Collected exploitation and prediction evidence
Risk source coverageCISA KEV is observed exploitation evidence. FIRST EPSS is a dated prediction of exploitation in the next 30 days. Missing scores are unknown. This collector requests predictions only for explicit CVE aliases in the public NuGet archive; Microsoft release views retain their existing prediction scope.
No collected risk observation for these identifiers. This does not establish absence of exploitation or a zero probability.
cve-program · CVE-2026-61628
Publishednginx ignition is a user interface for the nginx web server. Prior to version 2.41.1, `POST /api/users/onboarding/finish` is registered as anonymous (unauthenticated) and creates a user with full ReadWrite admin permissions. Because the handler uses a check-then-act (TOCTOU) pattern between the "onboarding already completed?" check and the user-creation write, with no atomic guard, a remote unauthenticated attacker who can reach an instance in its pre-onboarding state can create an administrator account for themselves — and concurrent requests can create multiple admin accounts in a single race. Version 2.41.1 patches the issue.
- Source published
- 21 Sep 2026 14:44:54 UTC
- Source modified
- 21 Sep 2026 15:12:59 UTC
- Observed here
- 23 Oct 2026 15:48:27 UTC
- Source terms
- CVE Program Terms of Use
Original source record · Cite this exact observation · Complete original publisher JSON
This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: cve-program · CVE Program Terms of Use. Source text is retained; field grouping and change labels are provided by ChangeIntel.
CVSS 3.1 · 8.1 CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
euvd · EUVD-2026-83947
Publishednginx ignition is a user interface for the nginx web server. Prior to version 2.41.1, `POST /api/users/onboarding/finish` is registered as anonymous (unauthenticated) and creates a user with full ReadWrite admin permissions. Because the handler uses a check-then-act (TOCTOU) pattern between the "onboarding already completed?" check and the user-creation write, with no atomic guard, a remote unauthenticated attacker who can reach an instance in its pre-onboarding state can create an administrator account for themselves — and concurrent requests can create multiple admin accounts in a single race. Version 2.41.1 patches the issue.
EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON.
Original publisher date fields
datePublished: Sep 21, 2026, 2:44:54 PM
dateUpdated: Sep 21, 2026, 3:12:59 PM
- Source published
- Sep 21, 2026, 2:44:54 PM (timezone not stated)
- Source modified
- Sep 21, 2026, 3:12:59 PM (timezone not stated)
- Observed here
- 11 Nov 2026 15:02:49 UTC
- Source terms
- ENISA EUVD · source terms and attribution apply
Original source record · Cite this exact observation · Complete original publisher JSON
This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: euvd · ENISA EUVD · source terms and attribution apply. Source text is retained; field grouping and change labels are provided by ChangeIntel.
EUVD CVSS 3.1 · 8.1 CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
nvd · CVE-2026-61628
Publishednginx ignition is a user interface for the nginx web server. Prior to version 2.41.1, `POST /api/users/onboarding/finish` is registered as anonymous (unauthenticated) and creates a user with full ReadWrite admin permissions. Because the handler uses a check-then-act (TOCTOU) pattern between the "onboarding already completed?" check and the user-creation write, with no atomic guard, a remote unauthenticated attacker who can reach an instance in its pre-onboarding state can create an administrator account for themselves — and concurrent requests can create multiple admin accounts in a single race. Version 2.41.1 patches the issue.
NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON.
Source analysis status: Awaiting Analysis
Weakness classifications: CWE-362
Original publisher date fields
published: 2026-09-21T15:17:30.290
lastModified: 2026-09-23T18:25:00.707
- Source published
- 21 Sep 2026 15:17:30 UTC
- Source modified
- 23 Sep 2026 18:25:00 UTC
- Observed here
- 25 Oct 2026 14:19:22 UTC
- Source terms
- NIST NVD usage terms; underlying source attribution retained
Original source record · Cite this exact observation · Complete original publisher JSON
This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: nvd · NIST NVD usage terms; underlying source attribution retained. Source text is retained; field grouping and change labels are provided by ChangeIntel.
CVSS 3.1 · [email protected] · Secondary · 8.1 CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
osv · GHSA-pxcx-fv34-x9p5
Published## Summary `POST /api/users/onboarding/finish` is registered as **anonymous (unauthenticated)** and creates a user with **full ReadWrite admin permissions**. Because the handler uses a check-then-act (TOCTOU) pattern between the "onboarding already completed?" check and the user-creation write, with no atomic guard, a remote unauthenticated attacker who can reach an instance in its pre-onboarding state can create an administrator account for themselves — and concurrent requests can create multiple admin accounts in a single race. ## Affected component - Endpoint: `POST /api/users/onboarding/finish` - Route registration: `api/user/routes.go:49` → `authorizer.AllowAnonymous(http.MethodPost, "/api/users/onboarding/finish")` - Handler: `api/user/onboarding_finish_handler.go` ## Technical details The route is explicitly allowed without authentication: ```go // api/user/routes.go:48-49 authorizer.AllowAnonymous(http.MethodGet, "/api/users/onboarding/status") authorizer.AllowAnonymous(http.MethodPost, "/api/users/onboarding/finish") ``` The handler reads the onboarding state, returns 403 if already finished, and otherwise creates a user with every permission set to ReadWrite: ```go // api/user/onboarding_finish_handler.go func (h onboardingFinishHandler) handle(ctx *gin.Context) { alreadyFinished, err := h.commands.OnboardingCompleted(ctx.Request.Context()) // (1) CHECK if err != nil { panic(err) } if alreadyFinished { ctx.Status(http.StatusForbidden) return } requestPayload := &userRequestDTO{} if err = ctx.BindJSON(requestPayload); err != nil { panic(err) } domainModel := converter.Wrap(ctx.Request.Context(), toDomain, requestPayload) domainModel.ID = uuid.New() domainModel.Enabled = true domainModel.Permissions = user.Permissions{ // full admin Hosts: user.ReadWriteAccessLevel, Streams: user.ReadWriteAccessLevel, Certificates: user.ReadWriteAccessLevel, Integrations: user.ReadWriteAccessLevel, AccessLists: user.ReadWriteAccessLevel, Settings: user.ReadWriteAccessLevel, Users: user.ReadWriteAccessLevel, NginxServer: user.ReadWriteAccessLevel, Caches: user.ReadWriteAccessLevel, // ...all remaining permissions ReadWrite/ReadOnly } if err = h.commands.Save(ctx.Request.Context(), domainModel, nil); err != nil { // (2) ACT panic(err) } // ...authenticates and returns a JWT for the new admin } ``` The gap between **(1)** `OnboardingCompleted()` and **(2)** `Save()` is not protected by a lock, transaction, or unique constraint. Two or more requests can each pass the `alreadyFinished == false` check before any of them commits, so every racing request proceeds to create an admin user and receive a valid admin JWT. ## Preconditions (stated honestly) This is exploitable when the instance is in a **pre-onboarding state**: 1. **Fresh deployment** — the time window between the service coming online and the legitimate operator completing onboarding. During this window any unauthenticated party who can reach the instance can register the first/an additional admin. The race lets an attacker slip an admin account in *alongside* the operator's, so the operator's onboarding appears to succeed normally while the attacker silently holds admin. 2. **State reset** — if onboarding state can return to "not completed" (e.g. all users removed), the endpoint reopens and becomes a repeatable unauthenticated admin-creation primitive. The single-request path is a setup-window exposure; the **race** is what turns "first legitimate admin" into "attacker also gets admin," and what allows multiple admin accounts to be minted from one burst. ## Proof of concept Against an instance that has not yet completed onboarding: ```bash # Fire concurrent onboarding-finish requests; multiple admin accounts are created, # each returning a valid admin JWT, despite the single-admin intent. for i in $(seq 1 20); do curl -s -X POST http://TARGET/api/users/onboarding/finish \ -H 'Content-Type: application/json' \ -d '{"username":"attacker'"$i"'","password":"P@ssw0rd123!"}' \ -o /dev/null -w "%{http_code}\n" & done wait # Multiple 200 responses (each with a login token) instead of exactly one 200 + N×403. ``` Each `200` response body contains a `userLoginResponseDTO` with a JWT granting full admin access (Hosts/Streams/Certificates/Settings/Users/NginxServer/AccessLists/Caches = ReadWrite). The attacker then has complete control of the nginx-ignition instance and the nginx server it manages. ## Impact - **Unauthenticated administrative account takeover** of a fresh (or reset) instance. - Full admin enables every downstream capability: creating hosts/routes, editing global and per-route nginx configuration, managing access lists and certificates, and controlling the nginx server process. (The config surface is itself injectable — see the related nginx-configuration-injection issues — so admin here is a path to SSRF / arbitrary nginx directives.) - The TOCTOU race additionally allows minting multiple admin accounts from a single concurrent burst, aiding persistence/stealth. ## Remediation 1. Make onboarding completion atomic: enforce a database-level unique constraint (e.g. "at most one onboarding user" / single-row guard) so concurrent creates collide, or wrap the check-and-create in a single transaction / mutex. 2. Re-check `OnboardingCompleted()` inside the same transaction that performs the insert, and abort on conflict. 3. Consider requiring a one-time setup token (printed to server logs / env at first boot) for the initial admin creation, eliminating the unauthenticated window entirely. --- *Finding ID: GM-4607*
- Source published
- 21 Sep 2026 21:54:42 UTC
- Source modified
- 28 Sep 2026 17:10:54 UTC
- Observed here
- 24 Oct 2026 13:19:41 UTC
- Source terms
- GitHub Advisory Database · CC-BY-4.0
Original source record · Cite this exact observation · Complete original publisher JSON
This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: osv · GitHub Advisory Database · CC-BY-4.0. Source text is retained; field grouping and change labels are provided by ChangeIntel.
CVSS_V3 · CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Publisher rating · HIGH
osv · GO-2026-6540
Publishednginx ignition has Unauthenticated Admin Account Creation via Onboarding Race Condition in github.com/lucasdillmann/nginx-ignition. NOTE: The source advisory for this report contains additional versions that could not be automatically mapped to standard Go module versions. (If this is causing false-positive reports from vulnerability scanners, please suggest an edit to the report.) The additional affected modules and versions are: github.com/lucasdillmann/nginx-ignition before v0.0.0-20260621194639-0586b4e55ab.
- Source published
- 28 Sep 2026 16:43:40 UTC
- Source modified
- 28 Sep 2026 17:00:26 UTC
- Observed here
- 24 Oct 2026 13:19:41 UTC
- Source terms
- OSV · upstream source license applies
Original source record · Cite this exact observation · Complete original publisher JSON
This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: osv · OSV · upstream source license applies. Source text is retained; field grouping and change labels are provided by ChangeIntel.