Repository navigation
fix(security): refuse the well-known default password on /api/cli/connect from off-loopback (#14486) - #14491
Merged
diegosouzapw merged 2 commits intoSep 24, 2026
Conversation
…nect from off-loopback #13679 blocks the shipped INITIAL_PASSWORD placeholder at /api/auth/login when the request is not loopback. /api/cli/connect verifies the same management password, mints an admin-scoped oma_ access token on success, and is not in LOCAL_ONLY_API_PREFIXES — so on a fresh install, where sync-env.mjs copies INITIAL_PASSWORD=CHANGEME out of .env.example, the public default could be exchanged for admin from anywhere the port is reachable. Same gate, same audit shape (cli.connect.insecure_default_blocked). Loopback pairing and any rotated password are untouched. Refs #14486.
This was referenced Sep 22, 2026
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Fecha o item 1 (high) da #14486, achado pela
insecure-defaults:audit(Trail of Bits) na bateria/omni-code-secde 09-21.O buraco
A #13679 tratou a senha-padrão pública como o que ela é — uma credencial conhecida por todo mundo — e passou a recusar o login com ela quando a requisição não vem de loopback (
src/app/api/auth/login/route.ts:171). O gate ficou só ali.POST /api/cli/connectverifica a mesma senha (verifyManagementPassword), e em caso de sucesso emite um access tokenoma_com escopoadmin(:120). A rota não está emLOCAL_ONLY_API_PREFIXES. Escripts/dev/sync-env.mjs:306-346copiaINITIAL_PASSWORD=CHANGEMEdo.env.examplepara o.envem todonpm install.Resultado numa instalação recém-feita: quem alcançasse a porta trocava a senha pública por um token admin. O aviso de boot existe, mas aviso não é controle — foi exatamente o raciocínio da #13679, que esta rota não herdou.
A correção
O mesmo gate, no mesmo formato, com a mesma trilha de auditoria (
cli.connect.insecure_default_blocked): se a senha é a well-known e a origem não é loopback →403, nenhum token emitido.O que não muda: parear a CLI do próprio host (loopback) continua funcionando — é o caminho que o operador precisa para rotacionar a senha; e qualquer senha já rotacionada continua funcionando de qualquer origem.
TDD
tests/unit/14486-cli-connect-insecure-default-gate.test.ts, três casos, vermelhos no tip antes da correção:CHANGEME403, sem token, entrada de auditoriaCHANGEMEOs dois casos positivos entraram verdes de propósito: são a prova de que o gate morde só onde deve.
Validação
57 asserções nas 12 suítes vizinhas (login #13679, managementPassword, authz, access-token scopes) — a única falha foi
authz-bypass AC-7, um teste com orçamento explícito dehot-reload <50ms: 9/9 no tip ocioso da .113, 8/9 neste devbox sob load 40, e minha mudança não toca essa área. Os 6 testes acrescentados aostryker.conf.jsonsão do tip, não desta PR.Refs #14486.