Skip to content

docs(auth): the "Reset Password with Token" example sends password, but the reset door requires newPassword and answers 400 #29852

Closed

Description

@objectstack-fleet

security#1 · os-justin · session_01QSeKYn5CmmdShCJifm6WYj

Filed by the seat from an os-dev run's out-of-scope finding (class a, reproducible). This is a documentation defect, not a security item.

What

content/docs/permissions/authentication.mdx, section "Reset Password with Token", shows the body { token, password } for POST /api/v1/auth/reset-password. The door's body schema (better-auth resetPassword) requires newPassword. Sent as documented, the request answers:

400 {"message":"[body.newPassword] Invalid input: expected string, received undefined","code":"VALIDATION_ERROR"}

The dev measured this through AuthManager.handleRequest at 35af63a44c (branch claude/sec-hardening-c). The door's behaviour is the same on main.

Fix

Change the example's field to newPassword, and check the other reset/verification examples on the same page against their doors' body schemas.

Dedupe words: reset-password newPassword docs example; authentication.mdx reset body.

Activity

  1. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: first-touch audit · p3 · domain:devx · pm:queue · 2026-11-03T07:53Z

    ⛔ Not a claim.

    • Read fresh. The "Reset Password with Token" example in content/docs/permissions/authentication.mdx sends password, but the door requires newPassword and answers 400. A documented example that fails, and a docs-only fix, so p3. The seat says it is not a security item.
    • Check the page's other reset and verification examples against their doors in the same PR.

    Generated by Claude Code

  2. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8

    Claim: PM loop round 1
    Session: session_017ihL2ebbZkr2QAEG1x7UC8
    Account: marchtian
    Branch: claude/issue-29852-reset-password-example
    Worktree: objectstack-issue-29852
    Domain: domain:devx
    Seat: domain:devx#2
    File surface: content/docs/permissions/authentication.mdx (the "Reset Password with Token" example and the other reset/verification examples on the same page). ⛔ No code change.
    Container & model: S, mode:subagent, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: medium
    Clause-②: no
    Metadata-protocol: none
    Responsibility: the docs page shows { token, password } for POST /api/v1/auth/reset-password, whose body schema (better-auth resetPassword) requires newPassword; no platform path corrects it; it reaches every reader who copies the example, and the door answers 400 VALIDATION_ERROR
    Thread-read: 6598331661
    Premise: holds (origin/main content/docs/permissions/authentication.mdx L296–308 still sends password)
    Serial constraints cleared: no open PR or live Claim: names content/docs/permissions/authentication.mdx; the last touch on main is 4be8a2e9 (#29964, merged)

  3. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8
    os-dev-report

    {
      "issue": 29852,
      "status": "done",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/30112",
      "head": "a438313442c54190990a2196dbfa98c93527ec64",
      "premise_still_valid": true,
      "files_changed": ["content/docs/permissions/authentication.mdx (+1/-1)"],
      "line_budget": "2 changed lines (+1/-1), threshold 3000: under",
      "gates": {
        "derived": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at a4383134: 45 commands",
        "results": "45/45 exit 0 (first pass: 41 exit 0, 4 exit 3 PREREQUISITE NOT MET for unbuilt @objectstack/lint, @objectstack/formula, @objectstack/client-react; rebuilt under os-verify-lock, VERDICT command-exit 0; reran: check:doc-formula-expressions 0, check:doc-security-posture 0, check:skill-examples 0, check:docs-transcript-drift 0)",
        "ran_reconciliation": "dispatch-gates --ran: 45 derived, 45 run, 0 NOT-MEASURED, 0 UNRUN (derived zero, every line carries an exit code); exit 0",
        "ci": "in_progress at report time; not waited on",
        "not_measured": "CI-only: ci.yml Build Docs, Plan Test Core shards, and type-check lanes (none touched by a docs-only diff)"
      },
      "os_check_mechanism": "check:skill-examples type-checks a marked block with tsc against built declarations; JSON.stringify accepts any object, so the gate cannot catch a wrong body field. It passes before and after the fix.",
      "examples_checked": [
        {"example": "POST /request-password-reset {email}", "schema": "better-auth@1.7.12 dist/api/routes/password.mjs requestPasswordReset: email required, redirectTo optional", "verdict": "matches"},
        {"example": "POST /reset-password {token, password}", "schema": "better-auth@1.7.12 dist/api/routes/password.mjs resetPassword: newPassword required, token optional", "verdict": "FIXED: password -> newPassword"},
        {"example": "POST /set-initial-password {newPassword}", "schema": "packages/plugins/plugin-auth/src/set-initial-password.ts reads newPassword", "verdict": "matches"},
        {"example": "POST /send-verification-email (no body, bearer)", "schema": "better-auth@1.7.12 dist/api/routes/email-verification.mjs requires email; fronted by packages/plugins/plugin-auth/src/send-verification-email.ts (auth-plugin.ts mount), which defaults email to the session's", "verdict": "matches"},
        {"example": "GET /verify-email?token=", "schema": "better-auth@1.7.12 dist/api/routes/email-verification.mjs verifyEmail query: token required, callbackURL optional", "verdict": "matches"},
        {"example": "POST /phone-number/send-otp {phoneNumber}", "schema": "better-auth@1.7.12 dist/plugins/phone-number/routes.mjs sendPhoneNumberOTPBodySchema", "verdict": "matches"},
        {"example": "POST /phone-number/verify {phoneNumber, code}", "schema": "dist/plugins/phone-number/routes.mjs verifyPhoneNumberBodySchema", "verdict": "matches"},
        {"example": "POST /phone-number/request-password-reset {phoneNumber}", "schema": "dist/plugins/phone-number/routes.mjs requestPasswordResetPhoneNumberBodySchema", "verdict": "matches"},
        {"example": "POST /phone-number/reset-password {phoneNumber, otp, newPassword}", "schema": "dist/plugins/phone-number/routes.mjs resetPasswordPhoneNumberBodySchema", "verdict": "matches"},
        {"example": "POST /two-factor/verify-totp {code}", "schema": "dist/plugins/two-factor/totp/index.mjs verifyTOTPBodySchema: code required, trustDevice optional", "verdict": "matches"},
        {"example": "GET /magic-link/verify?token=", "schema": "dist/plugins/magic-link/index.mjs magicLinkVerifyQuerySchema: token required", "verdict": "matches"}
      ],
      "deviations": [
        "none against the order; the merge commit of origin/main carries git's default message with no trailers"
      ],
      "mcp_calls": "0",
      "api_writes": "2 - fleet-write relay pr_create (POST pulls + labels leg, skip-changeset) and this comment via post-stamped; plus git push (not REST)",
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: none - the os:check marker proves a fetch example compiles, never that its body matches the door; noted in the PR acceptance notes, not filed"
      ]
    }
  4. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8

    Landed · PR #30112 merged as 5d7ada3e92 · 2026-11-04T15:29Z. ACCEPT record 6634151881. The card closed through Fixes; pm:dispatched comes off in this stroke.

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions