-
Notifications
You must be signed in to change notification settings - Fork 56
fix: v2.2.0 deep-audit remediation (4 HIGH, 6 MEDIUM) #505
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
735b043
fix: resolve v2.2.0 deep-audit findings (4 HIGH, 6 MEDIUM)
ndycode 4552c13
fix(audit): address CodeRabbit #505 review
ndycode aac8ce2
fix: resolve v2.2.0 deep-audit LOW findings
ndycode 4be2fc4
fix(audit): address CodeRabbit #505 second review (8 items)
ndycode 877e02f
fix(audit): CodeRabbit #505 round 3 + cut v2.2.1
ndycode 8e49838
fix(audit): close the 3 heavy concurrency gaps (#8/#9, #14)
ndycode 311d7cc
fix(audit): owner-safe config lock + CodeRabbit #505 round 4
ndycode fea2830
fix(audit): CRITICAL legacy-flagged migration deadlock + tone regex a…
ndycode File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| # v2.2.1 | ||
|
|
||
| Patch release. A full deep audit of the v2.2.0 tree (six parallel auditors across | ||
| auth, the runtime proxy/rotation, scripts/bins, quota/policy, storage, and the | ||
| codex-manager CLI, plus a live Windows/PowerShell repro) surfaced bugs that | ||
| escaped pre-release review. This release fixes 4 HIGH and 6 MEDIUM findings, 9 of | ||
| 12 LOW findings, and the issues raised across two rounds of automated review. | ||
|
|
||
| The headline fix: the `mcodex` launcher (the v2.2.0 flagship) was a bash script | ||
| shipped as a Windows bin and could not start on Windows when a WSL stub shadowed | ||
| git-bash on PATH. It is now a pure Node launcher with zero bash dependency. | ||
|
|
||
| ## Install | ||
|
|
||
| ```bash | ||
| npm i -g codex-multi-auth@latest | ||
| ``` | ||
|
|
||
| ## HIGH | ||
|
|
||
| - **mcodex is now a Node launcher (Windows-fatal fix).** `scripts/mcodex` was | ||
| `#!/usr/bin/env bash`; npm's generated `.cmd`/`.ps1` shim invoked bare `bash`, so | ||
| when the WSL stub (`System32\bash.exe`) or the WindowsApps app-execution alias | ||
| resolved before git-bash, `mcodex` died with `HCS_E_SERVICE_NOT_AVAILABLE`. The | ||
| launcher is rewritten in Node (`scripts/mcodex.js`): zero bash dependency on the | ||
| default forward path, `tmux`/`watch` invoked as argv arrays (no shell string | ||
| interpolation), and graceful degradation with the same friendly messages when | ||
| those POSIX tools are absent. The direct-run gate canonicalizes symlinks so the | ||
| launcher still runs when invoked through an npm-created symlink bin. | ||
| - **OAuth concurrent-login isolation.** The local callback server stored the | ||
| authorization `code`/`state` on the shared `http.Server` instance, so two logins | ||
| in one process could cross-bind callback state. Capture now lives in per-call | ||
| closures. | ||
| - **Capability matrix reads the correct key.** `model-capability-matrix` read | ||
| capability snapshots/boosts with the sha256 account key while the store is | ||
| written under the entitlement key, so the matrix reported every account as | ||
| supporting every model. It now reads with the entitlement key, matching the | ||
| write path. | ||
| - **Storage transaction deadlock.** A flagged-storage backup recovery that ran | ||
| inside an already-held storage lock re-acquired the global mutex and deadlocked, | ||
| wedging all subsequent account/token saves (reachable via the doctor restore | ||
| flow). Lock ownership is now tracked so recovery persists without re-locking. | ||
|
|
||
| ## MEDIUM | ||
|
|
||
| - **Status tone precedence.** A failed live health check whose detail also carried | ||
| a quota percentage could render the account's prefix green ("working") because | ||
| the failure keyword was trapped inside the `(NN%)` segment. The tone now | ||
| considers the whole detail, so a real failure always renders red. | ||
| - **`workspace` index validation.** `codex-multi-auth workspace 1.9` (or `2abc`) | ||
| was silently truncated to account 1/2 by `parseInt`. Non-integer indices are now | ||
| rejected with a clear "must be a positive integer" message, matching `switch`. | ||
| - **Unsupported-model classification.** A "the model … is not currently available | ||
| for this ChatGPT account" response was classified as a transient outage instead | ||
| of an entitlement block on one code path; the normalized wording is now detected | ||
| consistently across the probe/forecast/report/check surfaces. | ||
| - **Manual pin preserved on restore.** The combined account+flagged storage | ||
| transaction dropped `pinnedAccountIndex`/`affinityGeneration` when cloning, so a | ||
| doctor restore erased the user's manual pin. Both fields are now carried through. | ||
| - **Secret directory permissions.** The account-storage and quota-cache | ||
| directories are created `0o700` (and re-asserted on POSIX) instead of relying on | ||
| the umask, so they are not world-listable. | ||
| - **Forecast no longer recommends a blocked account.** Policy-blocked and | ||
| token-exhausted accounts were eligible for "pick shortest wait"; they are now | ||
| excluded, and the forecast returns no recommendation with a clear reason when | ||
| none are ready. | ||
|
|
||
| ## LOW and follow-up hardening | ||
|
|
||
| The same audit produced a series of lower-severity fixes, all included here: | ||
|
|
||
| - **Concurrency / Windows filesystem.** The local-client-token store serializes | ||
| its full read-modify-write and retries the complete transient lock taxonomy | ||
| (`EBUSY`/`EPERM`/`EAGAIN`/`ENOTEMPTY`/`EACCES`) on rename; `lastUsedAt` writes on | ||
| the bearer-verify hot path are debounced so steady-state verification stays | ||
| in-memory. The Codex CLI state cache honors `forceRefresh` even with a load in | ||
| flight, guarded by a load generation so a slow stale read can't overwrite a | ||
| fresh snapshot. The runtime proxy short-circuits storage re-reads on unchanged | ||
| mtime/size and checks authorization before path/method (401 before 404). | ||
| - **Config save coordination.** The env-path config save now retries a transient | ||
| `stat` lock and serializes its read-modify-write through a cross-process file | ||
| lock (modeled on the refresh-lease coordinator) in addition to the in-process | ||
| queue and the mtime compare-and-swap, closing the lost-update window. | ||
| - **Routing mutex selection race.** With `routingMutex="enabled"`, account | ||
| selection and the cursor commit now run inside a single, reentrant mutex | ||
| acquisition, so concurrent requests can no longer read the same cursor and | ||
| stampede the same account. Legacy mode is unchanged. | ||
| - **Smaller fixes.** `clampIndex` floors fractional indices and coerces `NaN`; | ||
| the `mcodex` launcher relays `SIGTERM`/`SIGINT` to its spawned child; | ||
| capability-policy eviction is LRU; the Codex bin resolver skips any PATH | ||
| candidate inside its own wrapper directory; secret directories re-assert | ||
| `0o700`; and `styleQuotaSummary` clamps out-of-range percentages. | ||
|
|
||
| Two findings are documented as intentional rather than changed: the device-auth | ||
| endpoint's bare 403/404 responses are its non-RFC-8628 "authorization pending" | ||
| signal (the poll already exits at the server deadline), and runtime budgets are | ||
| deliberately soft/eventually-consistent under concurrency. | ||
|
|
||
| ## Verification | ||
|
|
||
| Full test suite green (4,300+ tests, 40+ new regression cases); typecheck and | ||
| lint clean; the Node `mcodex` launcher, the `workspace` index guard, the live | ||
| `check`/`best`/`forecast` paths, and `verify --all` (the storage transaction | ||
| path) were all exercised against a real account on Windows/PowerShell. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dial back the tmux claim in these release notes.
the node rewrite is the real fix here, but this paragraph reads like tmux forwarding is fully corrected too. the pr notes still carry a tmux positional-args gap as follow-up, so saying
tmuxis handled cleanly overstates the shipped behavior. keep the windows/bash fix, signal relay, and symlink-gate details, but avoid implying full tmux argv fidelity until that lands. as per coding guidelines, "keep README, SECURITY, and docs consistent with actual CLI flags and workflows."🤖 Prompt for AI Agents