Every CVE Search/ Get API key

CVE-2026-61628

nginx ignition has Unauthenticated Admin Account Creation via Onboarding Race Condition

8.1 HighPublic exploitFix available

nginx 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.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
High
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
High

Exploit likelihood

0.43%Up 0.1 points since Sep 22, 2026
90%50%10%1%

What each source reports

CVE List Score used 8.1

nginx ignition has Unauthenticated Admin Account Creation via Onboarding Race Condition

nginx 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.

Record
CVE-2026-61628
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-362
Updated
2026-11-02
EUVDEUVD-2026-83947 8.1

nginx 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.

Record
EUVD-2026-83947
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Updated
2026-11-02
GitHub AdvisoriesGHSA-pxcx-fv34-x9p5 8.1

nginx ignition has Unauthenticated Admin Account Creation via Onboarding Race Condition

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:

// 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:

// 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:

# Fire concurrent onboarding-finish requests; multiple admin accounts are created,
# each returning a valid admin JWT,…
Record
GHSA-pxcx-fv34-x9p5
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-362
Updated
2026-11-02
NVD 8.1

nginx 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.

Record
CVE-2026-61628
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-362
Updated
2026-11-02
OSV 8.1

nginx ignition has Unauthenticated Admin Account Creation via Onboarding Race Condition

nginx 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.

Record
CVE-2026-61628
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-362
Updated
2026-11-02
OSVGHSA-pxcx-fv34-x9p5 8.1

nginx ignition has Unauthenticated Admin Account Creation via Onboarding Race Condition

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:

// 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:

// 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:

# Fire concurrent onboarding-finish requests; multiple admin accounts are created,
# each returning a valid admin JWT,…
Record
GHSA-pxcx-fv34-x9p5
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-362
Updated
2026-11-02
OSVUBUNTU-CVE-2026-61628 8.1

nginx 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.

Record
UBUNTU-CVE-2026-61628
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Updated
2026-11-02
OSVGO-2026-6540 No score

nginx ignition has Unauthenticated Admin Account Creation via Onboarding Race Condition in github.com/lucasdillmann/nginx-ignition

nginx 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.

Record
GO-2026-6540
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
github.com/lucasdillmann/nginx-ignition
Go
before 0.0.0-20260621194639-0586b4e55ab
0.0.0-20260621194639-0586b4e55ab
github.com/lucasdillmann/nginx-ignition
Go
All versions None known

Public exploits

Links only. Every CVE stores no exploit code.

Public exploits
SourceLinkDate
PoC in GitHubabraxas/CVE-2026-616282026-09-22

History

History
RecordedChangedSources
affected
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV, PoC in GitHub

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-61628 is a high vulnerability (CVSS 8.1) in Lucasdillmann Nginx-ignition, published September 21, 2026. Public exploit code exists. EPSS puts the chance of exploitation in the next 30 days at 0.43%, the 37th percentile. Fixed in github.com/lucasdillmann/nginx-ignition 0.0.0-20260621194639-0586b4e55ab.

References

Show 4 moreShow less
This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open