Skip to content

Race condition in HudsonPrivateSecurityRealm.doCreateFirstAccount allows multiple initial admin accounts #26027

@geeknik

Description

@geeknik

Jenkins and plugins versions report

Environment
 Jenkins: 2.545-SNAPSHOT
 OS: Linux - 6.12.11-200.fc41.x86_64
 Java: 25.0.1 - Red Hat, Inc. (OpenJDK 64-Bit Server VM)
 ---
 antisamy-markup-formatter:173.v680e3a_b_69ff3
 asm-api:9.9-185.va_6c6b_3348b_c3
 bootstrap5-api:5.3.8-895.v4d0d8e47fea_d
 bouncycastle-api:2.30.1.82-277.v70ca_0b_877184
 caffeine-api:3.2.3-194.v31a_b_f7a_b_5a_81
 checks-api:373.vfe7645102093
 cloudbees-folder:6.1073.va_7888eb_dd514
 commons-lang3-api:3.20.0-109.ve43756e2d2b_4
 commons-text-api:1.15.0-210.v7480a_da_70b_9e
 credentials:1453.v9b_a_29777a_b_fd
 display-url-api:2.217.va_6b_de84cc74b_
 echarts-api:6.0.0-1165.vd1283a_3e37d4
 font-awesome-api:7.1.0-882.v1dfb_771e3278
 instance-identity:203.v15e81a_1b_7a_38
 ionicons-api:94.vcc3065403257
 jackson2-api:2.19.2-408.v18248a_324cfe
 jquery3-api:3.7.1-594.vb_3864f326cf0
 junit:1380.v491ff054cd35
 mailer:525.v2458b_d8a_1a_71
 matrix-auth:3.2.9
 matrix-project:870.v9db_fcfc2f45b_
 plugin-util-api:6.1192.v30fe6e2837ff
 prism-api:1.30.0-630.va_e19d17f83b_0
 scm-api:724.v7d839074eb_5c
 script-security:1385.v7d2d9ec4d909
 structs:362.va_b_695ef4fdf9
 variant:70.va_d9f17f859e0
 workflow-api:1398.v67030756d3fb_
 workflow-step-api:710.v3e456cc85233
 workflow-support:1010.vb_b_39488a_9841

What Operating System are you using (both controller, and any agents involved in the problem)?

Fedora 43

Reproduction steps

  1. Initialize a clean Jenkins installation using HudsonPrivateSecurityRealm as the security realm.
  2. Ensure no user accounts have been created yet (initial setup state).
  3. Simultaneously send multiple concurrent POST requests to the /securityRealm/createFirstAccount endpoint with different usernames and valid account details.
  4. Verify the number of users created and their permissions.

Expected Results

Only the very first request should succeed in creating an account. All subsequent concurrent requests should fail with a 401 Unauthorized error (or similar) because a user already exists or is being created, preventing the creation of multiple initial administrator accounts.

Actual Results

A race condition exists in HudsonPrivateSecurityRealm.doCreateFirstAccount. The hasSomeUser() check is non-atomic and unsynchronized. In testing with 20 concurrent threads, 20 different user accounts were created, and all 20 were granted administrative privileges via tryToMakeAdmin(u).

Anything else?

The vulnerability is a classic Time-of-Check to Time-of-Use race condition in core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java between lines 366-376. While impact is limited to the initial setup phase, it allows an attacker to gain admin access if they can time requests during the window before the first user is fully persisted.

Are you interested in contributing a fix?

Yes, the fix involves adding a static lock object to synchronize the doCreateFirstAccount method. This ensures the hasSomeUser() check and subsequent user creation are atomic.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions