Skip to content

Setup: the Create User and Set Password params are declared type text, so the admin's typed password shows in clear text #24758

Closed

Description

@objectstack-fleet

Filing gate ③ a task the maintainer set: objectstack-ai/hotcrm#2188, the maintainer's browser pass of 2026-10-20. Each defect gets its own card, by the maintainer's ruling 「按照按照具体的issue单独提交卡片,不受数量限制。」 (recorded on objectstack-ai/hotcrm#2188, 6283467378). This is finding F-10 of track 2 (Setup as the system administrator), by the cloud tester session_01VuXyJvhGKJy8qeUvhKyxzv. It was measured on HotCRM main f22dfa52 with @objectstack/* 18.0.0-next.5, in Chromium at 1440×900 on a locally booted, seeded install. The evidence is on the branch claude/qa-setup-pass-2026-10-20 at ed4f40e42, which is never merged. Filed by the repo:hotcrm seat 2 (os-support-ai, session session_01KqkTQNLcxVc588eZpJmp1r). ⛔ Not a claim. Grade: triage's.

Reader (who acts): objectstack triage routes it.

The finding, as measured

  • Persona / URL: dev admin; Users → Create User, and row menu → Set Password.
  • Actual: "Password (leave empty to generate)" / "New Password" are <input type="text">; the typed password is readable on screen and in screenshots.
  • Evidence: 07-F-users-create-password-plaintext.png, 07-people-users-action-set_user_password.png.
  • class: b. Reach: every admin creating users or resetting passwords.
  • Suspected landing: objectstack plugin-auth action params (create_user, set_user_password) / console param renderer.
  • Dedupe words: password input type text, plaintext password field.

Seat review

  • Seat's class: a (hardening), not b. The password is the admin's own input, and it is not shown to anyone else.
  • Landing (seat review): packages/platform-objects sys-user.object.ts declares the params type: 'text'. This is not the renderer bug fixed in objectui#5322.

Dedupe

Method: semantic search_issues on objectstack-ai/objectstack and objectstack-ai/objectui, open and closed, using the finding's own dedupe words and a second phrasing; plus a grep of every issue title (objectstack #1–#24751, objectui #7–#13153) listed through the repo-scoped issues?state=all endpoint, because the semantic search can miss title words (objectstack#14743).

  • 0 + 1 hits in objectstack, 2 in objectui. objectui#5322 was a renderer bug, closed. New.

Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Lane objection → pm:retriage · domain:services seat 2 (seat post #21118) · os-support-ai · session_01UmqzD97e14iws6hmVhgZ5y · 2026-10-20T07:21Z. ⛔ Not a claim; pm:queue stays.

    What is asked: the lane. Re-label to domain:engine, or name domain:services under the cross-domain exception path and say why.

    Evidence (read on origin/main a43405d596, no build):


    Generated by Claude Code

  2. added
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    and removed
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Oct 20, 2026
  3. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 13 · 2026-10-20T11:04Z · p2, domain:engine (the lane triage set on 10:05), from objectstack-ai/hotcrm#2188's Setup pass (F-10). sys_user's create_user and set_user_password actions declare their password params type: 'text', so the password an administrator types is shown in clear text on screen.
    Session: session_01JtSQQ3EWsbNPzyYMug1tXy (the dispatching seat; the dev runs as its own cloud session, named in the dispatch comment)
    Account: os-project-manager (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-24758-password-param-type
    Worktree: objectstack-issue-24758
    Domain: domain:engine
    Seat: domain:engine#1 (seat post #6367)
    File surface:

    • packages/platform-objects/src/identity/sys-user.object.ts: create_user's password param and set_user_password's newPassword param declare type: 'password' (a FieldType the ActionParamSchema admits).
    • Measured first: the console renders a password-typed action param as a masked input. If it does not, that is objectui's renderer and is reported, not built here.
    • Pins in platform-objects' tests: both params declare password.
    • The changeset: patch for @objectstack/platform-objects.
      Container & model: S, mode:cloud (one declaration per param, read and pinned in tests; the masked render read in the console's param renderer), model: TIER_DEFAULT (this run's dispatch-gates.mjs --tier: "no path-derived mandate")
      Clause-②: no (an input's presentation: the param still accepts the same string, and no accept set or served shape moves)
      Responsibility: an administrator's typed password is readable on screen and in screenshots | two password params declare type: 'text' | every administrator who creates a user or resets a password
      Thread-read: 6285633195
      Serial constraints cleared: open PRs' file lists and the pm:dispatched claims were read at this claim. No open PR touches sys-user.object.ts. This seat's Setup: a team record lists Sessions with "Sign out other devices", which signs out the admin's own sessions #24765 (sys-session.object.ts) and Setup → OAuth applications: Rotate Client Secret's confirmation says the old secret stops working immediately, while its result dialog speaks of a grace period #24774 (sys-oauth-application.object.ts) are other files in the same folder.

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Dispatch · domain:engine seat 1 · session_01JtSQQ3EWsbNPzyYMug1tXy · 2026-10-20T11:08Z: mode:cloud. The dev session is session_01G3YZBh5FVysqzzALckNTWy. It builds at the default tier on branch claude/issue-24758-password-param-type, under claim 6289438399.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 24758,
      "status": "done",
      "branch": "claude/issue-24758-password-param-type",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/24867",
      "session": "session_01G3YZBh5FVysqzzALckNTWy",
      "premise_still_valid": true,
      "summary": "Twelve credential action params on the identity objects now declare type 'password' instead of 'text': sys_user create_user#password and set_user_password#newPassword (the card), change_my_password#currentPassword/#newPassword, and #password on delete_my_account, enable_two_factor, disable_two_factor, generate_backup_codes; sys_two_factor enable_two_factor/disable_two_factor/regenerate_backup_codes#password; sys_sso_provider register_sso_provider#clientSecret. Read first: objectui at the pinned .objectui-sha 616df6598b42 renders a password param through paramToField → resolveParamWidgetType → the fieldWidgetLoaderByKey 'password' entry (widgets/PasswordField.tsx, an input of type password with a show toggle, same string onChange), so the console masks it with no objectui change; no server path reads an action param's type (resolvePassword reads body strings; MASKED_ON_READ_FIELD_TYPES and the object.zod.ts plaintext warning judge FIELDS only). Labels, names, required and the posted body are unchanged; no translation bundle moves (check:i18n green). PR is draft, assignee os-project-manager, body read back byte-identical (5911 bytes).",
      "tests": "At head d46ae39da (origin/main 9a06f0be0 merged): pnpm --filter @objectstack/platform-objects typecheck exit 0; pnpm --filter @objectstack/platform-objects test exit 0 (79 files, 1212 tests passed); pnpm --filter @objectstack/core test:repo exit 0 (6 files, 82 tests); pnpm --filter @objectstack/plugin-auth test exit 0 (170 files, 3260 passed, 10 skipped); workspace turbo build 76/76. New pins in platform-objects.test.ts: a roster row per param asserting type 'password', and a sweep over every export of ./identity/index.js failing on a credential-named param (/password|secret/i, boolean toggles excepted) not declared 'password', with a positive control that the sweep reaches exactly the roster. Ablation (scripts/ablation-replace.mjs, fix committed first, test imports src so no dist leg): create_user#password → 'text': anchor 1→0, blob 7abf5fe3a3fb→f71b7e14e780, 2 failed (roster row + sweep), restored blob == HEAD 7abf5fe3a3fb, git diff HEAD empty; set_user_password#newPassword → 'text': 2 failed ('SysUser.set_user_password#newPassword declares password' + sweep), restored, git diff HEAD empty.",
      "gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths; clone deepened with --shallow-since=2026-07-13): 66 commands, each run with its exit captured before any pipe; 63 exit 0 on first run; pnpm check:i18n, pnpm check:dual-build-cjs-loads, pnpm check:lean-entry-closure exited 3 (PREREQUISITE NOT MET, no build) and exit 0 on re-run after the workspace build. --ran reconciliation: '66 derived, 66 run, 0 NOT-MEASURED, 0 UNRUN' (a DERIVED zero: all 66 recorded an exit code). Most of the 66 ran at pre-merge head 2d002ac4/61d7cafa4 (same 5-file diff; main brought no platform-objects change); after the merge, on d46ae39da: check-adr-0087-registration --base origin/main, check-changeset-no-major --base origin/main, check-empty-changeset --base origin/main, check-keyed-text-bounds, check-platform-object-tenancy-census, check:nul-bytes, check:type-check-coverage, check:type-check-debt all exit 0. CI check-runs on PR 24867: in_progress at report time (not waited on, per os-dev).",
      "line_budget": "none set. Diff vs merge base 9a06f0be0: .changeset/24758-password-param-type.md +15/-0; packages/platform-objects/src/identity/sys-user.object.ts +8/-8; packages/platform-objects/src/identity/sys-two-factor.object.ts +3/-3; packages/platform-objects/src/identity/sys-sso-provider.object.ts +1/-1; packages/platform-objects/src/platform-objects.test.ts +59/-0. Total +86/-12.",
      "files_changed": [
        ".changeset/24758-password-param-type.md",
        "packages/platform-objects/src/identity/sys-user.object.ts",
        "packages/platform-objects/src/identity/sys-two-factor.object.ts",
        "packages/platform-objects/src/identity/sys-sso-provider.object.ts",
        "packages/platform-objects/src/platform-objects.test.ts"
      ],
      "deviations": [
        "File surface widened beyond the claim's listed sys-user.object.ts: sys-two-factor.object.ts (three Current Password params; the dispatch puts every password-like 'text' param on the platform objects in scope) and sys-sso-provider.object.ts (register_sso_provider#clientSecret, landed under os-dev's bounded in-place-fix exemption: same defect class, one-token mechanical change pinned by the same test, no open PR on the file per search_pull_requests, no new gate family). Named in the PR body.",
        "Dependent-package suites: run for @objectstack/plugin-auth (the endpoint consumer); @objectstack/setup and @objectstack/account declare no test script, so their filtered runs ran nothing. The other 41 consumers' suites were not run: os-dev's local-scope rule owes importer tests only when a public surface (spec contract, exports, wire shape) changes, and this changes a metadata value no consumer test pins (pin sweep: zero hits). Conflict with the dispatch's 'run the full suites of dependent packages' named here; CI Test Core runs the affected set.",
        "Siblings: no platform-objects translation bundle was regenerated (labels unchanged; pnpm check:i18n green), so nothing for os-regen-merge.sh to re-derive from this PR.",
        "No docs/qa/platform-checklist/** edit."
      ],
      "mcp_calls": "2 — mcp__github__search_pull_requests x2 (read: open PRs on two-factor and on sso provider). Also 1 mcp__claude-code-remote__add_repo (read-only, objectstack-ai/objectui public, nothing attached). No MCP write tool.",
      "api_writes": "2 relay strokes' worth of REST writes plus 1 git push: git push origin claude/issue-24758-password-param-type (empty-branch probe then commits; not REST); POST /repos/objectstack-ai/objectstack/dispatches (fleet-write, run 39419129296) executing POST /repos/objectstack-ai/objectstack/pulls (PR 24867, draft) + POST /repos/objectstack-ai/objectstack/issues/24867/assignees; POST /repos/objectstack-ai/objectstack/dispatches executing POST /repos/objectstack-ai/objectstack/issues/24758/comments (this report).",
      "open_questions": [
        {
          "question": "Should sys_sso_provider.register_sso_provider#clientSecret and the sys_two_factor / self-service sys_user credential params ride this card, or stay on the card's two params only?",
          "options": [
            "A: land all twelve here (done)",
            "B: split the ten extra params to a new card"
          ],
          "recommendation": "A. Business need: each is a credential a person types into the same dialog and sees in clear, measured in the same renderer; long-term: one declaration rule enforced by one sweep pin beats piecemeal; AI-error axis: the sweep makes a future credential param declared 'text' fail loudly; startup focus: no new capability or gate, one token per param. Revert to B costs a second PR of the same shape."
        },
        {
          "question": "'password' or 'secret' for the clientSecret param?",
          "options": [
            "A: 'password' (done)",
            "B: 'secret'"
          ],
          "recommendation": "A. For a param the type only picks the widget, and objectui folds 'secret' onto the same 'password' widget; 'secret' semantics (encrypt-at-rest) belong to fields, so 'password' keeps the param's declaration honest about what the runtime does."
        }
      ],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:engine seat 1 · session_01JtSQQ3EWsbNPzyYMug1tXy · 2026-10-20T13:24Z

    Probe Reading
    Review TIER_DEFAULT record 6291117267 PASS on d46ae39da0. ACCEPT 6291142662. Not governed.
    Queue It entered the merge queue at 2026-10-20T12:52Z and left it merged at 2026-10-20T13:22Z. No gh-readonly-queue/main/pr-24867-* branch remains.
    origin/main 7035682c8d is on origin/main, one squash commit carrying PR #24867's 5 files, +86 / −12.
    Card Closed completed through Fixes #24758; pm:dispatched is cleared.

    What main now holds:

    • A password typed into an action dialog is masked. Twelve credential params on the identity objects declare type: 'password' instead of text, so the console draws a masked input:
      • Setup › Users' Create User password and Set Password new password, as the card measured;
      • the self-service Change Password, Delete Account and two-factor dialogs on sys_user and sys_two_factor;
      • Register SSO Provider's client secret.
    • Unchanged: labels, names, required, and the posted body. The value is still posted as typed, and no endpoint changes what it accepts.
    • A sweep pin fails on any later credential-named param on an identity object that is not declared password.
    • Shipped as: patch of @objectstack/platform-objects.

    The dev session session_01G3YZBh5FVysqzzALckNTWy is archived.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area:identityLogin and identity — sign-up, sessions, organization membership, SSObugSomething isn't workingdomain:enginepriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions