Repository navigation
fix(api): require HTTPS for custom Google Gemini base URLs (CWE-319) - #2033
easonLiangWorldedtech wants to merge 1 commit into
Conversation
googleGeminiBaseUrl is user-editable (settings, imported profiles) and the @google/genai client keeps API-key authentication for custom endpoints, so a cleartext base URL would send the API key over an insecure endpoint (CWE-319). Validate the endpoint before any request in createMessage and completePrompt: HTTPS is required; plain HTTP is accepted only for loopback test proxies (localhost, [::1], and literal 127.0.0.0/8 IPv4 hosts). Hostnames that merely resemble the loopback range (127.example.test, 127.0.0.a, 127.0.0.1.a, foo127.bar) or fall outside it (10.0.0.1) are rejected, as are non-HTTP schemes such as ftp://localhost and malformed URLs. Violations surface as a structured ApiProviderError before the request is built, so the key never leaves the process. Carved out of the abort-signal provider rollout (fork PR 1303) at the maintainer's request so the endpoint policy can be reviewed independently of the cancellation changes.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📜 Recent review details
📝 Summary
Merge Risk: ⚪ Minimal · up to
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
|
@coderabbitai review |
✅ Action performedReview finished.
|
Review statusThanks for contributing. This comment tracks the review sequence and the next action. Current step: Awaiting fresh human maintainer or CODEOWNER approval. Automated review is complete for the latest commit but does not replace human approval. Review-state labels are managed by this workflow; do not edit them manually. |
What this does
googleGeminiBaseUrlis user-editable (settings, imported profiles), and the@google/genaiclient keeps API-key authentication for custom endpoints. Before this PR a cleartext custom base URL was accepted as-is, so the API key could be sent over an insecure endpoint (CWE-319).This PR validates the custom endpoint before any request is built, in both
createMessageandcompletePrompt:http://localhost,http://[::1], and literal127.0.0.0/8IPv4 hosts.127.example.test,127.0.0.a,127.0.a.b,127.0.0.1.a,foo127.bar, and hosts outside the range such as10.0.0.1.ftp://localhost) and malformed URLs are rejected.ApiProviderError(provider/model/operation context) before the request is built, so the key never leaves the process.Content source
Carved out of the fork-side abort-signal provider rollout (fork PR #1303) at the maintainer's request: this endpoint policy changes which custom endpoints are accepted independently of cancellation, so separating it keeps that rollout reviewable. The helpers, guards, and security tests are ported from that rollout branch (the test block is re-nested to this file's structure); the rollout's timeout plumbing stays in that PR.
Budget
main.src/api/providers/gemini.ts(three module-private helpers plus two call-site guards); the remaining 513 lines are the security test matrix insrc/api/providers/__tests__/gemini.spec.ts.How to test
googleGeminiBaseUrltohttp://gemini.example.testand run any Gemini request → it fails with "Google Gemini base URL must use HTTPS (or a loopback HTTP endpoint for local test proxies)" before the request is sent.http://127.0.0.1:8080(orhttp://localhost,http://[::1]) → the request proceeds against the local proxy.src/:vitest run --globals api/providers/__tests__/gemini.spec.ts.Verification at this head
vitest run --globals --no-file-parallelism api/providers/__tests__/gemini.spec.ts api/providers/__tests__/gemini-handler.spec.ts→ 63/63 passed.gemini.tsguards turns exactly the 11 reject tests red while the 5 loopback-allow tests stay green in both directions; byte-exact restore returns all green.eslint --max-warnings=0on both changed files → 0 errors / 0 warnings; suppression counts unchanged.tsc --noEmit→ 0 errors.prettier --check→ clean.