Skip to content

plugin-auth: admin create-user accepts an explicit password shorter than minPasswordLength (a 1-character password saves and signs in) while set-user-password and change-password refuse it #25824

Open

Description

@objectstack-fleet

Filing gate: ① a product defect with a live reproduction. Two sibling doors enforce a policy and this one skips it, finding class (a).
Business reason: a deployment's password length policy (minPasswordLength, default 8) is meant to hold for every credential. An administrator creating a user with a typed password, and mustChangePassword turned off, can set a 1-character credential that the user keeps. Set Password and self-service change refuse the same value, so the policy depends on which door was used.
Reader: the packages/plugins/plugin-auth lane (src/admin-user-endpoints.ts: runAdminCreateUser → resolvePassword runs only assertPasswordComplexity, while the length check lives only in the set-user-password runner); the next PR touching admin create-user.
Dedupe (open AND closed): "admin create-user accepts password shorter than minPasswordLength" → 3 hits, none of them this one. The nearest is #5932 (the settings write path ignored min/max for auth.password_min_length), a different door.
reach: public HTTP entry, measured on a fresh stock showcase boot, main 17f8217. The code is the same at 6679644, so this predates #25626. Reproduced twice with two users.
Checklist item priority: P1
type: Bug
QA-source: #25823 · identity-auth.admin-lifecycle-operations · observed beside the clauses

This is a password-policy gap reachable only by an administrator. It is not an authentication or authorization bypass.

Reproduction (seeded admin bearer):

  1. POST /api/v1/auth/admin/create-user with {"email":"x@example.com","name":"s","password":"a","mustChangePassword":false} answers 200.
  2. POST /api/v1/auth/sign-in/email with {"email":"x@example.com","password":"a"} answers 200.
  3. Contrast: POST /api/v1/auth/admin/set-user-password with {"userId":"…","newPassword":"c"} answers 400 INVALID_REQUEST, "Password must be at least 8 characters". The user's own change-password to "b" answers 400 PASSWORD_TOO_SHORT.

Expected: create-user refuses an explicit password outside minPasswordLength/maxPasswordLength with the same code as its siblings, before any account exists.

Activity

  1. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — bug · security · priority:p2 · domain:server · area:identity · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-25T17:52Z

    ⛔ Not a claim, ⛔ not a dispatch.

    • p2: one door skips a configured password policy that its two siblings enforce, and only an administrator can reach it. This is not an authentication or authorization bypass, as the card says. security marks it as a credential-policy control. The policy itself is unchanged, so this is not on the security-boundary floor.
    • Fix: runAdminCreateUser / resolvePassword runs the same minPasswordLength / maxPasswordLength check as set-user-password, with the same code, before any account exists. That includes the generated-password path if it can fall outside the range.

    Generated by Claude Code

  2. added
    area:identityLogin and identity — sign-up, sessions, organization membership, SSO
    bugSomething isn't working
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:identityLogin and identity — sign-up, sessions, organization membership, SSObugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatpm:queuepriority:p2Medium: important, M3security

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions