Skip to content

fix(quota): enforce.ts não fail-open em limite 0/negativo/não-finito (hardening do #4830) - #4866

Closed
diegosouzapw wants to merge 119 commits into
release/v3.8.37from
fix/quota-enforce-fail-open-hardening
Closed

diegosouzapw wants to merge 119 commits into
release/v3.8.37from
fix/quota-enforce-fail-open-hardening

Conversation

@diegosouzapw

Copy link
Copy Markdown
Owner

Contexto

Hardening de segurança em src/lib/quota/enforce.ts, sobre o código mergeado no #4830. Uma revisão de segurança automatizada apontou um fail-open / control regression (MEDIUM) no guard de placeholder de cota.

Problema

if (!(dim.limit > Number.EPSILON)) continue;

Esse predicado pulava o enforcement para qualquer limit <= EPSILON, não só o placeholder documentado. Consequências:

  • limit = 0 (um operador configurando "bloquear tudo" no Wizard "Limite") → era silenciosamente liberado (fail-open).
  • limit negativo (config corrompida) → também pulado (fail-open).
  • NaN / Infinity → pulado silenciosamente.

Apenas Number.EPSILON é o placeholder real semeado em planRegistry.ts (glm/minimax/kimi-coding/deepseek = "configurar manualmente"). O predicado era largo demais.

Correção

if (dim.limit === Number.EPSILON) continue;          // único placeholder documentado
if (!Number.isFinite(dim.limit)) { log.warn(...); continue; }  // NaN/Infinity: observável
// 0 e negativo agora fluem para decideFairShare → block (global-saturated)
  • Igualdade exata com Number.EPSILON — o único valor placeholder semeado.
  • 0 e negativo passam a ser enforçados (deny). 0 = "bloquear tudo"; negativo = fail-closed.
  • NaN/Infinity (nem armazenáveis via provider_plans JSON) continuam pulados, mas com warn-log → bypass observável em vez de silencioso.

Validação (Hard Rule #18 — TDD)

tests/unit/quota-enforce-misconfigured-limit-blocks.test.ts (failing-then-passing):

  • limit=0 → block (antes: allow)
  • limit=-100 → block (antes: allow)

Regressão preservada: quota-epsilon-unconfigured-allow (EPSILON segue liberado), quota-division-blocks (enforcement de limite real), quota-enforce / quota-fair-share (19/19), quota-exclusive-catalog-4806 (#4806). typecheck:core limpo, lint 0, file-size OK.

Diego Rodrigues de Sa e Souza and others added 16 commits June 23, 2026 18:31
Integrated into release/v3.8.36 (#3501 chatCore extraction stack 1/13)
…3501) (#4824)

Integrated into release/v3.8.36 (#3501 chatCore extraction stack 2/13)
Integrated into release/v3.8.36 (#3501 chatCore extraction stack 3/13)
… completo, #3501) (#4817)

Integrated into release/v3.8.36 (#3501 chatCore extraction stack 4/13)
Integrated into release/v3.8.36 (#3501 chatCore extraction stack 5/13)
… usage non-streaming, #3501) (#4832)

Integrated into release/v3.8.36 (#3501 chatCore extraction stack 6/13)
…ardrail post-call, #3501) (#4831)

Integrated into release/v3.8.36 (#3501 chatCore extraction stack 7/13)
…n-streaming, #3501) (#4828)

Integrated into release/v3.8.36 (#3501 chatCore extraction stack 8/13)
…de resposta non-streaming, #3501) (#4835)

Integrated into release/v3.8.36 (#3501 chatCore extraction stack 9/13)
…streaming, #3501) (#4833)

Integrated into release/v3.8.36 (#3501 chatCore extraction stack 10/13)
…de resposta streaming, #3501) (#4836)

Integrated into release/v3.8.36 (#3501 chatCore extraction stack 11/13)
…-store streaming, #3501) (#4829)

Integrated into release/v3.8.36 (#3501 chatCore extraction stack 12/13)
…orms streaming, #3501) (#4837)

Integrated into release/v3.8.36 (#3501 chatCore extraction stack 13/13)
…ease-acceleration) (#4857)

* feat(quality): add check:test-runner-api gate (vitest-only dirs must use vitest API)

* feat(release): reusable CHANGELOG i18n-mirror sync script

* chore(ops): add prune-stale-worktrees.sh (dry-run by default)

* ci(quality): run test-runner-api + docs-all + vitest + full unit suite on PR->release fast-path

---------

Co-authored-by: Diego Rodrigues de Sa e Souza <souzamiriamrodrigues790@gmail.com>
… EPSILON não bloqueia (#4830)

Integrated into release/v3.8.36 — quota-exclusive qtSd/ listing (#4806) + EPSILON placeholder no longer blocks; rebuilt from stale base (3 defining commits cherry-picked clean over release tip)
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Integrated into release/v3.8.36 — Google Flow video-generation provider (#4569), release-green validated (typecheck + 21 tests + file-size)
…_CREDENTIALS (#4694, #4720) (#4796)

Integrated into release/v3.8.36 — auth on compression run-telemetry + OMNIROUTE_EVAL_CREDENTIALS doc, release-green validated (typecheck + 3 tests + env-doc-sync)
…rough (port from 9router#1157) (#4624)

Integrated into release/v3.8.36 — port (rebuilt from stale base; defining commit cherry-picked clean over release tip, release-green validated)
…rmat providers (#4625)

Integrated into release/v3.8.36 — port (rebuilt from stale base; defining commit cherry-picked clean over release tip, release-green validated)
…ocks (#4633)

Integrated into release/v3.8.36 — port (rebuilt from stale base; defining commit cherry-picked clean over release tip, release-green validated)
…thropic providers (#4650)

Integrated into release/v3.8.36 — port (rebuilt from stale base; defining commit cherry-picked clean over release tip, release-green validated)
…4651)

Integrated into release/v3.8.36 — port (rebuilt from stale base; defining commit cherry-picked clean over release tip, release-green validated)
Integrated into release/v3.8.36 — port (rebuilt from stale base; defining commit cherry-picked clean over release tip, release-green validated)
…4656)

Integrated into release/v3.8.36 — port (rebuilt from stale base; defining commit cherry-picked clean over release tip, release-green validated)
…ttings (#4659)

Integrated into release/v3.8.36 — port (rebuilt from stale base; defining commit cherry-picked clean over release tip, release-green validated)
) (#4629)

Integrated into release/v3.8.36 — kiro region SSRF guard (GHSA-6mwv-4mrm-5p3m), port rebuilt clean over release tip
)

Integrated into release/v3.8.36 — port rebuilt clean over release tip, release-green validated
diegosouzapw and others added 25 commits June 24, 2026 11:53
Integrated into release/v3.8.36
…d across dashboard pages (#4603) (#4960)

Integrated into release/v3.8.36 (fixes #4603)
…penai-to-claude streaming (#4951) (#4959)

Integrated into release/v3.8.36 (fixes #4951)
…efault (#4963)

Integrated into release/v3.8.36 — restores home topology card (#4596 regression)
…ld OOM) (#4968)

Integrated into release/v3.8.36 — fixes build OOM (optimizePackageImports open-sse)
…/ existentes [Fase 3 #9] (#4962)

Integrated into release/v3.8.36
…(hardening)

O guard de placeholder usava `!(dim.limit > Number.EPSILON)`, que pulava o
enforcement para QUALQUER limite <= EPSILON — incluindo um 0 configurado
("bloquear tudo") e valores negativos (config corrompida). Isso é um fail-open:
uma dimensão de cota que o operador setou para 0/negativo para negar tráfego
liberava silenciosamente todas as requests.

Aperta o skip para igualdade exata com o ÚNICO placeholder semeado
(`=== Number.EPSILON`, glm/minimax/kimi-coding/deepseek em planRegistry.ts).
Agora 0 e negativo fluem para decideFairShare e são enforçados (block
global-saturated); apenas limites não-finitos (NaN/Infinity — nem armazenáveis
via provider_plans JSON) são pulados, e com warn-log para tornar o bypass
observável em vez de silencioso.

TDD: tests/unit/quota-enforce-misconfigured-limit-blocks.test.ts — limit=0 e
limit=-100 agora retornam block (antes: allow); o teste do placeholder EPSILON
(quota-epsilon-unconfigured-allow) continua verde.

Finding de revisão de segurança automatizada (MEDIUM, fail-open/control
regression) sobre o #4830.
@diegosouzapw
diegosouzapw force-pushed the fix/quota-enforce-fail-open-hardening branch from 5968a56 to 4fdf68e Compare June 24, 2026 23:00
@diegosouzapw
diegosouzapw changed the base branch from release/v3.8.36 to release/v3.8.37 June 25, 2026 22:01
@diegosouzapw

Copy link
Copy Markdown
Owner Author

Fechando como duplicata. O commit definidor desta branch (4a1ae868) é o refactor extract safeParseJSON util, dedup tryParseJSON que já está no release/v3.8.37 (#4735) — jsonUtil.ts existe e geminiHelper.ts/openai-to-claude.ts já chamam safeParseJSON. O título da PR ("fix(quota): enforce.ts não fail-open") não corresponde ao commit do topo, e o hardening de quota titulado não está neste commit (o enforce.ts é fail-open by design, B16). Sem perda de cobertura. (verificado por trust-but-verify na leva 4)

@diegosouzapw
diegosouzapw deleted the fix/quota-enforce-fail-open-hardening branch June 26, 2026 22:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants