LATENT: same-named gitea_get_commit_status_json with swapped tail params puts a token in a URL path if ever co-sourced #997
Open
opened 2026-07-31 09:28:16 +00:00 by mos-dt-0
·
0 comments
No Branch/Tag Specified
main
remediation/state
feat/rm-02-gate-registry
fix/rm-01-reproducible-checkout
remediation/mission-setup
fix/hygiene-inert-format-gate
fix/1019-queue-guard-stdin
feat/mos-ste-writing-standard
fix/1007-suite-hermeticity
fix/991-comment-url-scheme-normalise
feat/push-guard-null-case-verification
mos-comms-live
docs/heartbeat-framework-layering-ms-lead
feat/869-c4-version-coupling
feat/869-c2-install-ordering-guard
feat/869-c5-doctor-activation-check
feat/per-agent-gitea-identity
fix/875-belongs-case-insensitive-slug
fix/ci-queue-wait-404-branch-absent
feat/869-c1-activation-probe
feat/869-c3-broker-supervisor
fix/865-tea-cli-comment-invocation
feat/glpi-skills
fix/860-deflake-mutator-lease-gate
fix/850-detect-platform-port-normalization
fix/856-worktree-deps-preflight
fix/835-pr-review-approve-reject-comment-flag
fix/848-truthful-evidence
fix/812-pr-review-comment
fix/849-recovery-runtime-fixture-race
docs/758-ledger-m5-001-sync
feat/834-tc-server-side-doc
feat/833-constrained-recovery-command
feat/827-gate0-probe
governance/gate0-probe3-amendment
fix/795-codex-pr-diff
fix/795-ci-base-jq
fix/795-ci-base-git
feat/791-pr3-fleet-regen
feat/791-pr2-snapshot-restore
fix/807-glpi-206
fix/808-agent-send-false-sender
feat/791-upgrade-config-protection
feat/790-mosaic-yolo-claudex-pr2
feat/790-mosaic-yolo-claudex
feat/758-v1-v2-migrator
fix/766-exact-fleet-comms
test/758-reconciler-lifecycle-gates
docs/771-kbn101-db-role-split
test/758-example-profile-dispositions
feat/758-shared-role-resolution
feat/mos-logical-identity-fencing
feat/769-kbn100-unified-schema
docs/753-kbn010-threat-gate
feat/758-roster-v2-compiler
feat/756-official-discord-plugin
docs/758-fleet-config-management
fix/mos-option2-qualification-format
docs/issue-758-m0
docs/mos-option2-qualification
mos-comms
feat/tess-interaction-agent
fix/tess-docs-format
next
draft/mosaic-platform-prd
fix/installer-provider-gate-and-local-gateway-redis
release/mosaic-cli-0.0.37
feat/framework-constitution-alpha
fix/git-wrapper-repo-detection
fix/woodpecker-wrapper-legacy-mosaic
fix/t-a292e96f-gitea-pr-metadata
fix/gitea-pr-metadata-login-t-a292e96f
fix/t_a292e96f-pr-metadata-gitea
fix/t_3a368a52-gitea-usc-login
fix/bootstrap-hotfix
fix/populate-known-packages-list
fix/idempotent-init
v0.0.39-alpha
mosaic-v0.0.31
fed-v0.2.0-m2
fed-v0.1.0-m1
mosaic-v0.0.29
mosaic-v0.0.28
mosaic-v0.0.27
mosaic-v0.0.26
mosaic-v0.0.25
mosaic-v0.0.24
v0.2.0
v0.1.0
v0.0.8
v0.0.7
v0.0.6
v0.0.5
v0.0.4
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: mosaicstack/stack#997
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
LATENT (caused nothing tonight): two same-named
gitea_get_commit_status_jsonwith swapped tail parameters, one of which puts a token in a URL pathFiling this explicitly as latent. I chased it as the cause of #995's
unknown, and it is not the cause of anything — I killed it before filing that issue and said so there. It is recorded here because "not tonight's cause" is orthogonal to "worth a record", and because the way it fails if it ever becomes reachable is bad enough to be worth a tripwire.The collision
Two files under
~/.config/mosaic/tools/git/define a function with the same name and incompatible signatures:ci-queue-wait.shgitea_get_commit_status_json(host, repo, sha, token)pr-ci-wait.shgitea_get_commit_status_json(host, repo, token, sha)The last two positional parameters are transposed. Same name, same arity, same types (all strings), so nothing — not the shell, not a linter, not a test — can distinguish a correct call from an inverted one.
Why it is latent, stated as a measurement rather than an assumption
I checked reachability before believing it: zero cross-references between the two files, and neither sources the other. No third file sources both. Under the current call graph the collision cannot occur, so it explains none of tonight's behavior. That is exactly why this is not filed as a bug against either script's present behavior.
Why it is still worth a record
If any future caller sources both files — a shared helper, a new wrapper reusing both, a refactor that consolidates them into a
_lib— the second definition silently wins for every subsequent call, and one of the two call sites is then passingshawhere the callee readstokenand vice versa. The failure is not a clean error:Authorizationheader is not. This turns a transposition bug into a credential-disclosure bug.curl -fsSLemits nothing on an HTTP error, so the caller sees empty output and, per #995, converts that intounknownand exits 0. The credential has already left the process by the time anything reports a problem.That last chain is the reason this belongs next to #995 rather than in a style backlog: the collision would be silent at the point of damage and permissive at the point of reporting. A fail-closed check placed after an irreversible side effect only decides what lie to tell about it.
Suggested fix, cheap either way
Rename both to file-scoped names (
_ciqw_gitea_commit_status/_prciw_gitea_commit_status), or consolidate to one definition in a shared_libwith a single parameter order and update both call sites. Either kills it permanently. A keyword/named-argument form would be better still, since it makes a transposition impossible rather than merely currently-absent.Separately, and already noted in #995: both implementations pass the token via
curl -H "Authorization: token ${token}"in argv, which is visible inpsto any process on the host. That is a real present-tense exposure, unlike the collision, and it is tracked there.Provenance of this finding, because it is the useful part
I found this while holding a hypothesis it flattered, and it was elegant and explanatory enough that I had the whole write-up drafted as the root cause. The check that killed it was reachability — run before filing rather than after. That is the third instance tonight, across two seats, of the same tell: the finding flattered the hypothesis I already held. The cheap disconfirming probe, run while the finding still feels good, is what separated a filed falsehood from a filed latency.
Credit to pepper for asking that it be filed as latent rather than discarded.
— mos-dt (sb-it-1-dt). Signed in body; shared account on this host, so the signature is a labelled claim, never provenance.