Fase 8 · Bloco D — injection-guard em todas as rotas LLM + red-team - #3857
Conversation
…ments/instructions (Fase 8 D.A)
… default) (Fase 8 D.B2)
…rpus (Fase 8 D2.1)
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Code Review
This pull request expands prompt injection guard coverage across multiple API routes by wrapping POST handlers with withInjectionGuard, updating the input sanitizer to extract more fields, and adding red-team configurations and unit tests. The reviewer feedback highlights a critical bug in extractMessageContents where string inputs still trigger a memory-intensive character-by-character iteration (char-split). Additionally, the reviewer raises valid architectural concerns regarding the application of the injection guard to non-generative endpoints (such as moderations, embeddings, rerank, and search) where there is no execution risk and guarding may block legitimate use cases or degrade performance.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| } | ||
| } | ||
|
|
||
| if (typeof body.input === "string") contents.push(body.input); |
There was a problem hiding this comment.
Correção Incompleta do Bug de Char-Split em Embeddings
Embora esta linha adicione a string completa de body.input ao array contents, ela não impede o comportamento de char-split que ocorre no loop anterior (linhas 120-135).
Como const messages = body.messages || body.input || []; faz o fallback para body.input quando body.messages é indefinido, se body.input for uma string, o loop for (const msg of messages) ainda irá iterar sobre cada caractere individual da string e adicioná-lo ao contents (já que typeof msg === "string" é verdadeiro para cada caractere).
Para inputs grandes de embeddings (com milhares de caracteres), isso causa um overhead de memória massivo e executa as regexes de injeção/PII milhares de vezes desnecessariamente.
Correção Recomendada
Modifique a linha 120 (fora deste diff) para garantir que messages seja atribuído apenas se for realmente um array:
const messages = Array.isArray(body.messages) ? body.messages : (Array.isArray(body.input) ? body.input : []);| return response; | ||
| } | ||
|
|
||
| export const POST = withInjectionGuard(postHandler); |
There was a problem hiding this comment.
Problema Arquitetural: Guarding em Endpoint de Moderação
Aplicar o withInjectionGuard ao endpoint /v1/moderations é contraproducente e introduz um problema crítico de usabilidade:
- Sem Risco de Execução: Endpoints de moderação não executam instruções nem geram respostas de LLM; eles apenas classificam o texto. Portanto, não são vulneráveis a ataques de prompt injection.
- Bloqueia Casos de Uso Legítimos: O propósito principal de um endpoint de moderação é verificar se um input (que pode conter textos adversariais ou prompt injections) é seguro. Se o
INJECTION_GUARD_MODEestiver definido comoblock, qualquer cliente tentando moderar um prompt injection será bloqueado com um erroSECURITY_001, quebrando completamente o fluxo de moderação.
Recomendamos excluir /v1/moderations do wrapper de proteção contra injeção.
| }); | ||
| } | ||
|
|
||
| export const POST = withInjectionGuard(postHandler); |
There was a problem hiding this comment.
Problema Arquitetural: Guarding em Endpoint de Embeddings
Aplicar o withInjectionGuard ao endpoint /v1/embeddings é desnecessário e introduz problemas de performance e funcionais:
- Sem Risco de Execução: Modelos de embedding não executam instruções; eles apenas geram representações vetoriais do texto de entrada. Não são vulneráveis a prompt injection.
- Overhead de Performance: Inputs de embeddings podem ser extremamente grandes (documentos inteiros). Executar verificações de injeção baseadas em regex em textos grandes adiciona latência e uso de CPU significativos a uma rota de dados de alta vazão.
- Bloqueia Casos de Uso Legítimos: Se um cliente estiver gerando embeddings para um dataset que contém exemplos de prompts ou textos adversariais, essas requisições serão bloqueadas no modo
block.
Recomendamos excluir /v1/embeddings do wrapper de proteção contra injeção.
| ); | ||
| } | ||
|
|
||
| export const POST = withInjectionGuard(postHandler); |
There was a problem hiding this comment.
Problema Arquitetural: Guarding em Endpoint de Rerank
Aplicar o withInjectionGuard ao endpoint /v1/rerank é desnecessário e introduz problemas funcionais:
- Sem Risco de Execução: Modelos de rerank apenas computam scores de relevância entre queries e documentos; eles não executam instruções.
- Bloqueia Casos de Uso Legítimos: Se um usuário buscar ou reordenar documentos que contenham exemplos de prompt injection ou documentação de segurança, a requisição será bloqueada no modo
block.
Recomendamos excluir /v1/rerank do wrapper de proteção contra injeção.
| } | ||
| } | ||
|
|
||
| export const POST = withInjectionGuard(postHandler); |
There was a problem hiding this comment.
Problema Arquitetural: Guarding em Endpoint de Busca
Aplicar o withInjectionGuard ao endpoint /v1/search é desnecessário e introduz problemas funcionais:
- Sem Risco de Execução: Endpoints de busca executam pesquisas na web; eles não executam instruções.
- Bloqueia Casos de Uso Legítimos: Se um usuário pesquisar por termos que contenham padrões de prompt injection ou tópicos de segurança, a requisição será bloqueada no modo
block.
Recomendamos excluir /v1/search do wrapper de proteção contra injeção.
…ributors Audited every commit since v3.8.24 and filled the gaps the [3.8.25] section was missing: a New Features section (compression engines + Compression Studios #3848, compression UI #3860, injection-guard #3857, kiro discovery #3836, Veo #3839, mimocode proxy #3837, Arena ELO flag #3821), 9 more Fixed entries (#3811/#3807/#3759/#3849/#3838/#3835/#3814/#3820/#3819), a Security section (CCR IDOR #3859, supply-chain #3824), and an Internal/Quality section. Every contributor and issue reporter is now credited.
* chore(release): continue v3.8.25 development cycle after main code-sync (r5) main fast-forwarded to release/v3.8.25 (#3863): unblocked Build+Docker via #3864, plus #3837 (mimocode proxy) and #3862 (trivy bump). This marker re-opens the umbrella PR for further v3.8.25 work. No version bump. * fix(db): persist the Keep-latest-backups retention setting (#3834) (#3867) * fix(oauth): clear GitLab Duo setup message instead of 500 (#3861) (#3868) * test(oauth): prove refresh_token preserved on real gemini-cli/antigravity dispatch (#3850) (#3869) * feat(compression-ui): unified compression config UI — per-engine pages + combos editor + menu + WS default-on (#3860) Integrated into release/v3.8.25 — feat(compression-ui): unified compression configuration UI (Compression Hub + per-engine Lite/Aggressive/Ultra pages + combos editor + sidebar entry + live-WS default-on). File-size re-baselined for sidebarVisibility.ts/chatCore.ts growth; orphan ws test relocated to a collected path. * docs(changelog): complete the v3.8.25 release notes + credit all contributors Audited every commit since v3.8.24 and filled the gaps the [3.8.25] section was missing: a New Features section (compression engines + Compression Studios #3848, compression UI #3860, injection-guard #3857, kiro discovery #3836, Veo #3839, mimocode proxy #3837, Arena ELO flag #3821), 9 more Fixed entries (#3811/#3807/#3759/#3849/#3838/#3835/#3814/#3820/#3819), a Security section (CCR IDOR #3859, supply-chain #3824), and an Internal/Quality section. Every contributor and issue reporter is now credited. * docs(changelog): restore + complete the v3.8.25 release notes Re-adds CHANGELOG.md (a prior server-side commit accidentally dropped it) with the complete, audited [3.8.25] section: New Features, the full Fixed list, Security & Hardening, and Internal/Quality — every contributor and issue reporter credited. * chore(release): finalize v3.8.25 — reconcile CHANGELOG + i18n mirrors, document OMNIROUTE_MAX_PENDING_MIGRATIONS, green the unit suite Release-gate reconciliation for v3.8.25: - CHANGELOG: dated 2026-06-14, linked #3826, rolled up file-size re-baselines (#3823/#3833), recorded the test-greening; re-synced all 41 i18n CHANGELOG mirrors. - Documented OMNIROUTE_MAX_PENDING_MIGRATIONS (#3416) in .env.example + ENVIRONMENT.md. - Greened the unit suite (was merged red on 4 CI shards): aligned 10 stale tests to this cycle's intended behavior (#3838/#3822/#3501/SOCKS5/Vertex-Express/Antigravity) and the same-provider 503 fall-through test; de-flaked the compression benchmark reproducibility and ServiceSupervisor crash tests. No production code changed. * ci(security): clear OpenSSF Scorecard code-scanning noise + harden workflow token permissions The Security tab held 155 open alerts, ALL from the advisory OpenSSF Scorecard tool (#3824) — supply-chain/posture scores, not code vulnerabilities — which drowned out real CodeQL findings. - scorecard.yml: stop uploading SARIF to the code-scanning tab (drop the upload-sarif step + the now-unused security-events: write). The run still produces the OpenSSF badge (publish_results) and a downloadable SARIF artifact. - TokenPermissions hardening (the high-severity, genuinely-valuable subset): set each workflow's top-level token to read-only and grant the exact writes at the job level that needs them — npm-publish (id-token/packages on publish jobs), docker-publish (packages on build), electron-release (contents on build/release, id-token/packages on publish-npm), build-fork (packages on build), claude (empty top-level; job grants its own). The 155 existing alerts were dismissed. Not adopting repo-wide SHA-pinning (143 PinnedDependencies advisories) — declined. * test(integration): align stale wiring/socks5 integration tests to this cycle's behavior These were red on the CI Integration job (pre-existing). No production code changed: - integration-wiring: the combos page no longer renders a per-page EmailPrivacyToggle (#3822 consolidated it into Settings → Appearance); the provider-detail test-result masking and upstream-proxy copy moved to decomposed components (#3501 BatchTestResultsModal / UpstreamProxyCard) — assertions now read the owning files. - api-routes-critical: SOCKS5 is now enabled by default (opt-out), so the disabled- rejection test must set ENABLE_SOCKS5_PROXY=false explicitly (an unset env now means enabled). (The ~32 live-Gemini integration tests are gated on OMNIROUTE_API_KEY and skip in CI; they only 'fail' locally when that key is present without a running server.)
…iegosouzapw#3857) Integrated into release/v3.8.25 — Fase 8 Bloco D (injection-guard em todas as rotas LLM + red-team).
* chore(release): continue v3.8.25 development cycle after main code-sync (r5) main fast-forwarded to release/v3.8.25 (diegosouzapw#3863): unblocked Build+Docker via diegosouzapw#3864, plus diegosouzapw#3837 (mimocode proxy) and diegosouzapw#3862 (trivy bump). This marker re-opens the umbrella PR for further v3.8.25 work. No version bump. * fix(db): persist the Keep-latest-backups retention setting (diegosouzapw#3834) (diegosouzapw#3867) * fix(oauth): clear GitLab Duo setup message instead of 500 (diegosouzapw#3861) (diegosouzapw#3868) * test(oauth): prove refresh_token preserved on real gemini-cli/antigravity dispatch (diegosouzapw#3850) (diegosouzapw#3869) * feat(compression-ui): unified compression config UI — per-engine pages + combos editor + menu + WS default-on (diegosouzapw#3860) Integrated into release/v3.8.25 — feat(compression-ui): unified compression configuration UI (Compression Hub + per-engine Lite/Aggressive/Ultra pages + combos editor + sidebar entry + live-WS default-on). File-size re-baselined for sidebarVisibility.ts/chatCore.ts growth; orphan ws test relocated to a collected path. * docs(changelog): complete the v3.8.25 release notes + credit all contributors Audited every commit since v3.8.24 and filled the gaps the [3.8.25] section was missing: a New Features section (compression engines + Compression Studios diegosouzapw#3848, compression UI diegosouzapw#3860, injection-guard diegosouzapw#3857, kiro discovery diegosouzapw#3836, Veo diegosouzapw#3839, mimocode proxy diegosouzapw#3837, Arena ELO flag diegosouzapw#3821), 9 more Fixed entries (diegosouzapw#3811/diegosouzapw#3807/diegosouzapw#3759/diegosouzapw#3849/diegosouzapw#3838/diegosouzapw#3835/diegosouzapw#3814/diegosouzapw#3820/diegosouzapw#3819), a Security section (CCR IDOR diegosouzapw#3859, supply-chain diegosouzapw#3824), and an Internal/Quality section. Every contributor and issue reporter is now credited. * docs(changelog): restore + complete the v3.8.25 release notes Re-adds CHANGELOG.md (a prior server-side commit accidentally dropped it) with the complete, audited [3.8.25] section: New Features, the full Fixed list, Security & Hardening, and Internal/Quality — every contributor and issue reporter credited. * chore(release): finalize v3.8.25 — reconcile CHANGELOG + i18n mirrors, document OMNIROUTE_MAX_PENDING_MIGRATIONS, green the unit suite Release-gate reconciliation for v3.8.25: - CHANGELOG: dated 2026-06-14, linked diegosouzapw#3826, rolled up file-size re-baselines (diegosouzapw#3823/diegosouzapw#3833), recorded the test-greening; re-synced all 41 i18n CHANGELOG mirrors. - Documented OMNIROUTE_MAX_PENDING_MIGRATIONS (diegosouzapw#3416) in .env.example + ENVIRONMENT.md. - Greened the unit suite (was merged red on 4 CI shards): aligned 10 stale tests to this cycle's intended behavior (diegosouzapw#3838/diegosouzapw#3822/diegosouzapw#3501/SOCKS5/Vertex-Express/Antigravity) and the same-provider 503 fall-through test; de-flaked the compression benchmark reproducibility and ServiceSupervisor crash tests. No production code changed. * ci(security): clear OpenSSF Scorecard code-scanning noise + harden workflow token permissions The Security tab held 155 open alerts, ALL from the advisory OpenSSF Scorecard tool (diegosouzapw#3824) — supply-chain/posture scores, not code vulnerabilities — which drowned out real CodeQL findings. - scorecard.yml: stop uploading SARIF to the code-scanning tab (drop the upload-sarif step + the now-unused security-events: write). The run still produces the OpenSSF badge (publish_results) and a downloadable SARIF artifact. - TokenPermissions hardening (the high-severity, genuinely-valuable subset): set each workflow's top-level token to read-only and grant the exact writes at the job level that needs them — npm-publish (id-token/packages on publish jobs), docker-publish (packages on build), electron-release (contents on build/release, id-token/packages on publish-npm), build-fork (packages on build), claude (empty top-level; job grants its own). The 155 existing alerts were dismissed. Not adopting repo-wide SHA-pinning (143 PinnedDependencies advisories) — declined. * test(integration): align stale wiring/socks5 integration tests to this cycle's behavior These were red on the CI Integration job (pre-existing). No production code changed: - integration-wiring: the combos page no longer renders a per-page EmailPrivacyToggle (diegosouzapw#3822 consolidated it into Settings → Appearance); the provider-detail test-result masking and upstream-proxy copy moved to decomposed components (diegosouzapw#3501 BatchTestResultsModal / UpstreamProxyCard) — assertions now read the owning files. - api-routes-critical: SOCKS5 is now enabled by default (opt-out), so the disabled- rejection test must set ENABLE_SOCKS5_PROXY=false explicitly (an unset env now means enabled). (The ~32 live-Gemini integration tests are gated on OMNIROUTE_API_KEY and skip in CI; they only 'fail' locally when that key is present without a running server.)
…iegosouzapw#3857) Integrated into release/v3.8.25 — Fase 8 Bloco D (injection-guard em todas as rotas LLM + red-team).
* chore(release): continue v3.8.25 development cycle after main code-sync (r5) main fast-forwarded to release/v3.8.25 (diegosouzapw#3863): unblocked Build+Docker via diegosouzapw#3864, plus diegosouzapw#3837 (mimocode proxy) and diegosouzapw#3862 (trivy bump). This marker re-opens the umbrella PR for further v3.8.25 work. No version bump. * fix(db): persist the Keep-latest-backups retention setting (diegosouzapw#3834) (diegosouzapw#3867) * fix(oauth): clear GitLab Duo setup message instead of 500 (diegosouzapw#3861) (diegosouzapw#3868) * test(oauth): prove refresh_token preserved on real gemini-cli/antigravity dispatch (diegosouzapw#3850) (diegosouzapw#3869) * feat(compression-ui): unified compression config UI — per-engine pages + combos editor + menu + WS default-on (diegosouzapw#3860) Integrated into release/v3.8.25 — feat(compression-ui): unified compression configuration UI (Compression Hub + per-engine Lite/Aggressive/Ultra pages + combos editor + sidebar entry + live-WS default-on). File-size re-baselined for sidebarVisibility.ts/chatCore.ts growth; orphan ws test relocated to a collected path. * docs(changelog): complete the v3.8.25 release notes + credit all contributors Audited every commit since v3.8.24 and filled the gaps the [3.8.25] section was missing: a New Features section (compression engines + Compression Studios diegosouzapw#3848, compression UI diegosouzapw#3860, injection-guard diegosouzapw#3857, kiro discovery diegosouzapw#3836, Veo diegosouzapw#3839, mimocode proxy diegosouzapw#3837, Arena ELO flag diegosouzapw#3821), 9 more Fixed entries (diegosouzapw#3811/diegosouzapw#3807/diegosouzapw#3759/diegosouzapw#3849/diegosouzapw#3838/diegosouzapw#3835/diegosouzapw#3814/diegosouzapw#3820/diegosouzapw#3819), a Security section (CCR IDOR diegosouzapw#3859, supply-chain diegosouzapw#3824), and an Internal/Quality section. Every contributor and issue reporter is now credited. * docs(changelog): restore + complete the v3.8.25 release notes Re-adds CHANGELOG.md (a prior server-side commit accidentally dropped it) with the complete, audited [3.8.25] section: New Features, the full Fixed list, Security & Hardening, and Internal/Quality — every contributor and issue reporter credited. * chore(release): finalize v3.8.25 — reconcile CHANGELOG + i18n mirrors, document OMNIROUTE_MAX_PENDING_MIGRATIONS, green the unit suite Release-gate reconciliation for v3.8.25: - CHANGELOG: dated 2026-06-14, linked diegosouzapw#3826, rolled up file-size re-baselines (diegosouzapw#3823/diegosouzapw#3833), recorded the test-greening; re-synced all 41 i18n CHANGELOG mirrors. - Documented OMNIROUTE_MAX_PENDING_MIGRATIONS (diegosouzapw#3416) in .env.example + ENVIRONMENT.md. - Greened the unit suite (was merged red on 4 CI shards): aligned 10 stale tests to this cycle's intended behavior (diegosouzapw#3838/diegosouzapw#3822/diegosouzapw#3501/SOCKS5/Vertex-Express/Antigravity) and the same-provider 503 fall-through test; de-flaked the compression benchmark reproducibility and ServiceSupervisor crash tests. No production code changed. * ci(security): clear OpenSSF Scorecard code-scanning noise + harden workflow token permissions The Security tab held 155 open alerts, ALL from the advisory OpenSSF Scorecard tool (diegosouzapw#3824) — supply-chain/posture scores, not code vulnerabilities — which drowned out real CodeQL findings. - scorecard.yml: stop uploading SARIF to the code-scanning tab (drop the upload-sarif step + the now-unused security-events: write). The run still produces the OpenSSF badge (publish_results) and a downloadable SARIF artifact. - TokenPermissions hardening (the high-severity, genuinely-valuable subset): set each workflow's top-level token to read-only and grant the exact writes at the job level that needs them — npm-publish (id-token/packages on publish jobs), docker-publish (packages on build), electron-release (contents on build/release, id-token/packages on publish-npm), build-fork (packages on build), claude (empty top-level; job grants its own). The 155 existing alerts were dismissed. Not adopting repo-wide SHA-pinning (143 PinnedDependencies advisories) — declined. * test(integration): align stale wiring/socks5 integration tests to this cycle's behavior These were red on the CI Integration job (pre-existing). No production code changed: - integration-wiring: the combos page no longer renders a per-page EmailPrivacyToggle (diegosouzapw#3822 consolidated it into Settings → Appearance); the provider-detail test-result masking and upstream-proxy copy moved to decomposed components (diegosouzapw#3501 BatchTestResultsModal / UpstreamProxyCard) — assertions now read the owning files. - api-routes-critical: SOCKS5 is now enabled by default (opt-out), so the disabled- rejection test must set ENABLE_SOCKS5_PROXY=false explicitly (an unset env now means enabled). (The ~32 live-Gemini integration tests are gated on OMNIROUTE_API_KEY and skip in CI; they only 'fail' locally when that key is present without a running server.)
…ributors Audited every commit since v3.8.24 and filled the gaps the [3.8.25] section was missing: a New Features section (compression engines + Compression Studios diegosouzapw#3848, compression UI diegosouzapw#3860, injection-guard diegosouzapw#3857, kiro discovery diegosouzapw#3836, Veo diegosouzapw#3839, mimocode proxy diegosouzapw#3837, Arena ELO flag diegosouzapw#3821), 9 more Fixed entries (diegosouzapw#3811/diegosouzapw#3807/diegosouzapw#3759/diegosouzapw#3849/diegosouzapw#3838/diegosouzapw#3835/diegosouzapw#3814/diegosouzapw#3820/diegosouzapw#3819), a Security section (CCR IDOR diegosouzapw#3859, supply-chain diegosouzapw#3824), and an Internal/Quality section. Every contributor and issue reporter is now credited.
…iegosouzapw#3857) Integrated into release/v3.8.25 — Fase 8 Bloco D (injection-guard em todas as rotas LLM + red-team).
* chore(release): continue v3.8.25 development cycle after main code-sync (r5) main fast-forwarded to release/v3.8.25 (diegosouzapw#3863): unblocked Build+Docker via diegosouzapw#3864, plus diegosouzapw#3837 (mimocode proxy) and diegosouzapw#3862 (trivy bump). This marker re-opens the umbrella PR for further v3.8.25 work. No version bump. * fix(db): persist the Keep-latest-backups retention setting (diegosouzapw#3834) (diegosouzapw#3867) * fix(oauth): clear GitLab Duo setup message instead of 500 (diegosouzapw#3861) (diegosouzapw#3868) * test(oauth): prove refresh_token preserved on real gemini-cli/antigravity dispatch (diegosouzapw#3850) (diegosouzapw#3869) * feat(compression-ui): unified compression config UI — per-engine pages + combos editor + menu + WS default-on (diegosouzapw#3860) Integrated into release/v3.8.25 — feat(compression-ui): unified compression configuration UI (Compression Hub + per-engine Lite/Aggressive/Ultra pages + combos editor + sidebar entry + live-WS default-on). File-size re-baselined for sidebarVisibility.ts/chatCore.ts growth; orphan ws test relocated to a collected path. * docs(changelog): complete the v3.8.25 release notes + credit all contributors Audited every commit since v3.8.24 and filled the gaps the [3.8.25] section was missing: a New Features section (compression engines + Compression Studios diegosouzapw#3848, compression UI diegosouzapw#3860, injection-guard diegosouzapw#3857, kiro discovery diegosouzapw#3836, Veo diegosouzapw#3839, mimocode proxy diegosouzapw#3837, Arena ELO flag diegosouzapw#3821), 9 more Fixed entries (diegosouzapw#3811/diegosouzapw#3807/diegosouzapw#3759/diegosouzapw#3849/diegosouzapw#3838/diegosouzapw#3835/diegosouzapw#3814/diegosouzapw#3820/diegosouzapw#3819), a Security section (CCR IDOR diegosouzapw#3859, supply-chain diegosouzapw#3824), and an Internal/Quality section. Every contributor and issue reporter is now credited. * docs(changelog): restore + complete the v3.8.25 release notes Re-adds CHANGELOG.md (a prior server-side commit accidentally dropped it) with the complete, audited [3.8.25] section: New Features, the full Fixed list, Security & Hardening, and Internal/Quality — every contributor and issue reporter credited. * chore(release): finalize v3.8.25 — reconcile CHANGELOG + i18n mirrors, document OMNIROUTE_MAX_PENDING_MIGRATIONS, green the unit suite Release-gate reconciliation for v3.8.25: - CHANGELOG: dated 2026-06-14, linked diegosouzapw#3826, rolled up file-size re-baselines (diegosouzapw#3823/diegosouzapw#3833), recorded the test-greening; re-synced all 41 i18n CHANGELOG mirrors. - Documented OMNIROUTE_MAX_PENDING_MIGRATIONS (diegosouzapw#3416) in .env.example + ENVIRONMENT.md. - Greened the unit suite (was merged red on 4 CI shards): aligned 10 stale tests to this cycle's intended behavior (diegosouzapw#3838/diegosouzapw#3822/diegosouzapw#3501/SOCKS5/Vertex-Express/Antigravity) and the same-provider 503 fall-through test; de-flaked the compression benchmark reproducibility and ServiceSupervisor crash tests. No production code changed. * ci(security): clear OpenSSF Scorecard code-scanning noise + harden workflow token permissions The Security tab held 155 open alerts, ALL from the advisory OpenSSF Scorecard tool (diegosouzapw#3824) — supply-chain/posture scores, not code vulnerabilities — which drowned out real CodeQL findings. - scorecard.yml: stop uploading SARIF to the code-scanning tab (drop the upload-sarif step + the now-unused security-events: write). The run still produces the OpenSSF badge (publish_results) and a downloadable SARIF artifact. - TokenPermissions hardening (the high-severity, genuinely-valuable subset): set each workflow's top-level token to read-only and grant the exact writes at the job level that needs them — npm-publish (id-token/packages on publish jobs), docker-publish (packages on build), electron-release (contents on build/release, id-token/packages on publish-npm), build-fork (packages on build), claude (empty top-level; job grants its own). The 155 existing alerts were dismissed. Not adopting repo-wide SHA-pinning (143 PinnedDependencies advisories) — declined. * test(integration): align stale wiring/socks5 integration tests to this cycle's behavior These were red on the CI Integration job (pre-existing). No production code changed: - integration-wiring: the combos page no longer renders a per-page EmailPrivacyToggle (diegosouzapw#3822 consolidated it into Settings → Appearance); the provider-detail test-result masking and upstream-proxy copy moved to decomposed components (diegosouzapw#3501 BatchTestResultsModal / UpstreamProxyCard) — assertions now read the owning files. - api-routes-critical: SOCKS5 is now enabled by default (opt-out), so the disabled- rejection test must set ENABLE_SOCKS5_PROXY=false explicitly (an unset env now means enabled). (The ~32 live-Gemini integration tests are gated on OMNIROUTE_API_KEY and skip in CI; they only 'fail' locally when that key is present without a running server.)
Fase 8 · Bloco D — Segurança-LLM (cobertura do injection-guard + red-team)
Último bloco da Fase 8. Fecha um gap real de segurança: o injection-guard estava em só 3 de ~14 rotas que aceitam prompt. Estende a cobertura a todas + red-team nightly.
D1 — Cobertura do guard (PRODUÇÃO)
extractMessageContents): agora cobreprompt(str/array),input-string (corrige char-split de embeddings),query+documents(rerank),instructions(Responses) — além demessages/input[]/system.withInjectionGuard): passa a emitir o bloco canônico{ code: "SECURITY_001" }+ CORS.export const POST = withInjectionGuard(handler)):messages,responses,images/generations,images/edits,videos/generations,music/generations,audio/speechembeddings,rerank,search,moderationsINJECTION_GUARD_MODE(defaultwarn= só loga, não bloqueia). Cobrir todas as rotas não introduz false-block (inclusive embeddings/moderations); o operador habilitablockglobalmente quando quiser.moderationsincluída por consistência (isentável viaresolveDisabledGuardrails).D2 — Red-team (nightly)
promptfooconfig.yaml+ corpus OWASP-LLM): valida que as rotas bloqueiam injeção emINJECTION_GUARD_MODE=block(asserterror.code === "SECURITY_001", sem custo — bloqueio antes do upstream). Quality-rubric + garak (probes promptinject/dan/leakreplay) gatedif: secrets.PROMPTFOO_PROVIDER_KEY != ''(skip-if-no-secret).nightly-llm-security.yml(cron + dispatch).Validação local (TDD)
system_override+system_prompt_leak; warn não bloqueia) · 73/73 testes de guardrails existentes (zero regressão) ·typecheck:core0 · configs parse ·check:test-discovery0 órfãos ·check:doc-linksPASS · promptfoo/garak provados no 1º nightly (Hard Rule fix(ci): add environment for npm token access #18 op2).Limitação conhecida (follow-up)
O wrapper guarda bodies JSON; rotas que aceitam
multipart/form-data(ex.:images/editscom upload) têm cobertura parcial — o wrapper no-opa com segurança em body não-JSON (sem false-block, mas sem extração do prompt nesses casos). Migrar as 3 rotas inline para o wrapper + cobrir form-data ficam no backlog.Doc:
docs/security/GUARDRAILS.md§ "Injection-guard route coverage & red-team".🤖 Generated with Claude Code