mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-09 17:28:51 +00:00
fix(release): v3.8.46 closing — proxy random via crypto.randomInt (CodeQL #698/#699) + date [3.8.46]
Some checks failed
Publish Fork Image to GHCR / Build and Push Fork Image (push) Waiting to run
CI / Change Classification (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Quality Ratchet (push) Blocked by required conditions
CI / Quality Gates (Extended) (push) Waiting to run
CI / Docs Sync (Strict) (push) Waiting to run
CI / Docs Lint (prose — advisory) (push) Waiting to run
CI / i18n UI Coverage (push) Waiting to run
CI / i18n Validation (all languages) (push) Waiting to run
CI / PR Test Policy (push) Waiting to run
CI / Build (push) Blocked by required conditions
CI / Package Artifact (push) Blocked by required conditions
CI / Electron Package Smoke (push) Blocked by required conditions
CI / Unit Tests (1/8) (push) Blocked by required conditions
CI / Unit Tests (2/8) (push) Blocked by required conditions
CI / Unit Tests (3/8) (push) Blocked by required conditions
CI / Unit Tests (4/8) (push) Blocked by required conditions
CI / Unit Tests (5/8) (push) Blocked by required conditions
CI / Unit Tests (6/8) (push) Blocked by required conditions
CI / Unit Tests (7/8) (push) Blocked by required conditions
CI / Unit Tests (8/8) (push) Blocked by required conditions
CI / Vitest (MCP / autoCombo / UI components) (push) Blocked by required conditions
CI / Coverage (push) Blocked by required conditions
CI / SonarQube (push) Blocked by required conditions
CI / PR Coverage Comment (push) Blocked by required conditions
CI / E2E Tests (1/9) (push) Blocked by required conditions
CI / E2E Tests (2/9) (push) Blocked by required conditions
CI / E2E Tests (3/9) (push) Blocked by required conditions
CI / E2E Tests (4/9) (push) Blocked by required conditions
CI / E2E Tests (5/9) (push) Blocked by required conditions
CI / E2E Tests (6/9) (push) Blocked by required conditions
CI / E2E Tests (7/9) (push) Blocked by required conditions
CI / E2E Tests (8/9) (push) Blocked by required conditions
CI / E2E Tests (9/9) (push) Blocked by required conditions
CI / Integration Tests (1/2) (push) Blocked by required conditions
CI / Integration Tests (2/2) (push) Blocked by required conditions
CI / Security Tests (push) Blocked by required conditions
CI / CI Dashboard (push) Blocked by required conditions
Publish to Docker Hub / Resolve Docker release metadata (push) Waiting to run
Publish to Docker Hub / Build Docker (linux/amd64) (push) Blocked by required conditions
Publish to Docker Hub / Build Docker (linux/arm64) (push) Blocked by required conditions
Publish to Docker Hub / Publish multi-arch manifests (push) Blocked by required conditions
OpenSSF Scorecard / Scorecard analysis (push) Waiting to run
semgrep / semgrep (push) Waiting to run
Wiki Sync / Sync wiki with docs (push) Has been cancelled
Some checks failed
Publish Fork Image to GHCR / Build and Push Fork Image (push) Waiting to run
CI / Change Classification (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Quality Ratchet (push) Blocked by required conditions
CI / Quality Gates (Extended) (push) Waiting to run
CI / Docs Sync (Strict) (push) Waiting to run
CI / Docs Lint (prose — advisory) (push) Waiting to run
CI / i18n UI Coverage (push) Waiting to run
CI / i18n Validation (all languages) (push) Waiting to run
CI / PR Test Policy (push) Waiting to run
CI / Build (push) Blocked by required conditions
CI / Package Artifact (push) Blocked by required conditions
CI / Electron Package Smoke (push) Blocked by required conditions
CI / Unit Tests (1/8) (push) Blocked by required conditions
CI / Unit Tests (2/8) (push) Blocked by required conditions
CI / Unit Tests (3/8) (push) Blocked by required conditions
CI / Unit Tests (4/8) (push) Blocked by required conditions
CI / Unit Tests (5/8) (push) Blocked by required conditions
CI / Unit Tests (6/8) (push) Blocked by required conditions
CI / Unit Tests (7/8) (push) Blocked by required conditions
CI / Unit Tests (8/8) (push) Blocked by required conditions
CI / Vitest (MCP / autoCombo / UI components) (push) Blocked by required conditions
CI / Coverage (push) Blocked by required conditions
CI / SonarQube (push) Blocked by required conditions
CI / PR Coverage Comment (push) Blocked by required conditions
CI / E2E Tests (1/9) (push) Blocked by required conditions
CI / E2E Tests (2/9) (push) Blocked by required conditions
CI / E2E Tests (3/9) (push) Blocked by required conditions
CI / E2E Tests (4/9) (push) Blocked by required conditions
CI / E2E Tests (5/9) (push) Blocked by required conditions
CI / E2E Tests (6/9) (push) Blocked by required conditions
CI / E2E Tests (7/9) (push) Blocked by required conditions
CI / E2E Tests (8/9) (push) Blocked by required conditions
CI / E2E Tests (9/9) (push) Blocked by required conditions
CI / Integration Tests (1/2) (push) Blocked by required conditions
CI / Integration Tests (2/2) (push) Blocked by required conditions
CI / Security Tests (push) Blocked by required conditions
CI / CI Dashboard (push) Blocked by required conditions
Publish to Docker Hub / Resolve Docker release metadata (push) Waiting to run
Publish to Docker Hub / Build Docker (linux/amd64) (push) Blocked by required conditions
Publish to Docker Hub / Build Docker (linux/arm64) (push) Blocked by required conditions
Publish to Docker Hub / Publish multi-arch manifests (push) Blocked by required conditions
OpenSSF Scorecard / Scorecard analysis (push) Waiting to run
semgrep / semgrep (push) Waiting to run
Wiki Sync / Sync wiki with docs (push) Has been cancelled
Post-release closing fixes: crypto.randomInt for proxy-pool random rotation (silences CodeQL js/insecure-randomness #698/#699) + date the [3.8.46] CHANGELOG section. See PR #6580.
This commit is contained in:
parent
92715c8f2c
commit
1eae976b28
46 changed files with 59 additions and 47 deletions
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
---
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
@ -142,6 +142,7 @@
|
|||
- **fix(api):** `POST /api/github-skills` now Zod-validates its request body; documented the new quality-gate env vars and pinned the merge-integrity GitHub Actions to a commit SHA.
|
||||
- **fix(skills):** generate the missing `omni-github-skills` registry entry and align the agent-skills catalog-count tests (follow-up to #6186).
|
||||
- **fix(quality):** clear the cycle's 11 net-new ESLint errors and make `validate-release-green` suppressions-aware.
|
||||
- **fix(security):** proxy-pool `random` rotation now selects via `crypto.randomInt` instead of `Math.random` — silences the post-release CodeQL `js/insecure-randomness` alerts (#698/#699) that flagged `Math.random` flowing into the selected proxy's credentials. Load-balancing selection is not a secret, but the crypto source is unbiased and clears the alert at the origin (#6365 follow-up).
|
||||
|
||||
### 📝 Maintenance
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"_rebaseline_2026_07_07_v3846_proxy_insecure_random": "PR #6580 (v3.8.46 post-release closing fix): proxies.ts 1173->1177 (+4) — o fix de segurança CodeQL #698/#699 troca Math.random por crypto.randomInt no random rotation strategy (#6365) e adiciona 4 linhas de comentário explicando por que (a seleção flui para credenciais do proxy). Crescimento irreducivel do proprio fix; frozen so encolhe daqui.",
|
||||
"_rebaseline_2026_07_07_v3846_release_close": "Release v3.8.46 Phase 0 (generate-release) — drift de ciclo absorvido no fechamento (fast-gates PR->release nao rodam check:file-size). PROD god-files crescidos por merges do ciclo (nao meus; DECOMPOR idealmente, debt #3501): proxies.ts 1060->1173, chat.ts 1681->1751, ApiManagerPageClient.tsx 3058->3120, ProxyRegistryManager.tsx 1125->1437 (feature de proxy). TEST frozen: models-catalog-route.test.ts 1600->1605 (+5 do fix#2 do captain, #6408 catalogo cache), vscode-token-routes.test.ts 1212->1285 (cycle drift + os asserts effort_tiers/supportsThinking do #6241 alinhados no release-PR-CI base-red), que adiciona o import + 2 chamadas do hook __resetCatalogBuilderRunsForTest existente no setup (harness, sem asserts). Shrink estrutural rastreado no roadmap #3501.",
|
||||
"_rebaseline_2026_07_04_v3844_release_close": "Release v3.8.44 Phase 0 (generate-release): drift de ciclo absorvido no fechamento, medido no tip 415d159c8 (fast-gates PR->release nao rodam check:file-size). oauth/[provider]/[action]/route.ts 924->960 (#6054 zed keychain-import 400 gracioso; PR #6158 aberto extrai o guard e restaura o freeze — quando mergear, o frozen so encolhe), providerLimits.ts 982->998 (#6139 TOCTOU quota recovery + #6128), chat.ts 1647->1662 (#6057 per-request Auto-Combo X-OmniRoute-Mode/Budget + #6097), auth.ts 2405->2426 (#6139 + #6090 quota preflight lockouts + #5943 codex session affinity). Crescimento irreducivel em chokepoints existentes, coberto por testes por-PR; shrink estrutural rastreado no roadmap #3501.",
|
||||
"_rebaseline_2026_07_03_v3844_ipfilter_release_green": "testFrozen bumps: models-catalog-route 1507->1600, perplexity-web 959->999, route-edge-coverage 1234->1241 (last is my #5975 comment +7). v3.8.44 cycle drift measured on release tip 32e4c906e during the #6131/#5975 release-green rebaseline. Inherited from the merge burst (Quality Ratchet does not run on PR->release fast-gates). route-edge-coverage +7 is my #5975 test comment; the rest is parallel-session drift. Tighten via --update next cycle.",
|
||||
|
|
@ -234,7 +235,7 @@
|
|||
"src/lib/db/migrationRunner.ts": 1125,
|
||||
"src/lib/db/models.ts": 1259,
|
||||
"src/lib/db/providers.ts": 1107,
|
||||
"src/lib/db/proxies.ts": 1173,
|
||||
"src/lib/db/proxies.ts": 1177,
|
||||
"src/lib/db/settings.ts": 1155,
|
||||
"src/lib/db/usageAnalytics.ts": 925,
|
||||
"src/lib/evals/evalRunner.ts": 961,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## [3.8.31] — 2026-06-20
|
||||
|
||||
## [3.8.46] — TBD
|
||||
## [3.8.46] — 2026-07-07
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
// (Vercel Edge, Deno Deploy, or Cloudflare Workers) instead of an undici ProxyAgent. All relay
|
||||
// types share the exact same x-relay-target / x-relay-path / x-relay-auth header spec; only the
|
||||
// deployment surface differs.
|
||||
import { randomUUID } from "crypto";
|
||||
import { randomUUID, randomInt } from "crypto";
|
||||
import { getDbInstance } from "./core";
|
||||
import { backupDbFile } from "./backup";
|
||||
import type {
|
||||
|
|
@ -722,7 +722,7 @@ function getOrCreateRotationRow(
|
|||
/**
|
||||
* Pick one member from an already-alive candidate list according to the scope's
|
||||
* rotation strategy. Assumes `candidates` is non-empty and ordered by position.
|
||||
* Round-robin uses (and persists) a monotonic cursor; random uses Math.random;
|
||||
* Round-robin uses (and persists) a monotonic cursor; random uses crypto.randomInt;
|
||||
* sticky holds the current member until its window elapses, then advances.
|
||||
*/
|
||||
function pickFromCandidates<T>(
|
||||
|
|
@ -736,7 +736,11 @@ function pickFromCandidates<T>(
|
|||
const state = getOrCreateRotationRow(db, normalizedScope, rotationScopeId);
|
||||
|
||||
if (state.strategy === "random") {
|
||||
return candidates[Math.floor(Math.random() * candidates.length)];
|
||||
// crypto.randomInt (unbiased, uniform in [0, length)) instead of Math.random —
|
||||
// CodeQL js/insecure-randomness flags Math.random flowing into the selected proxy's
|
||||
// credentials (a "security context"). Load-balancing selection is not a secret, but
|
||||
// crypto.randomInt silences the alert at the source and is unbiased (#6365 follow-up).
|
||||
return candidates[randomInt(candidates.length)];
|
||||
}
|
||||
|
||||
if (state.strategy === "sticky") {
|
||||
|
|
|
|||
|
|
@ -166,11 +166,17 @@ test("random strategy always returns a member of the alive set", async () => {
|
|||
await proxiesDb.setScopeRotationStrategy("provider", "mistral", "random");
|
||||
|
||||
const aliveHosts = new Set([a.host, b.host, c.host]);
|
||||
const seen = new Set<string>();
|
||||
for (let i = 0; i < 30; i++) {
|
||||
const r = await proxiesDb.resolveProxyForScopeFromRegistry("provider", "mistral");
|
||||
const host = (r as { proxy: { host: string } }).proxy.host;
|
||||
assert.ok(aliveHosts.has(host), `random pick ${host} must be an alive pool member`);
|
||||
seen.add(host);
|
||||
}
|
||||
// The random strategy uses crypto.randomInt (not Math.random — CodeQL js/insecure-randomness).
|
||||
// Over 30 picks from a 3-member alive pool it must vary, not stick on one member
|
||||
// (P(all 30 identical) ≈ (1/3)^29 ≈ 0). Guards that randomInt selection is uniform-ish.
|
||||
assert.ok(seen.size >= 2, `random strategy must vary its pick (saw only: ${[...seen].join(", ")})`);
|
||||
});
|
||||
|
||||
test("setScopeRotationStrategy round-trips via getScopeRotationStrategy", async () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue