Problem
The Gemini adapter embeds the API key directly in the URL query parameter (?key=...) at crates/nyro-core/src/proxy/adapter.rs:92-98:
fn build_url(&self, base_url: &str, path: &str, api_key: &str) -> String {
let url = format!("{}{path}", base_url.trim_end_matches('/'));
if url.contains('?') {
format!("{url}&key={api_key}")
} else {
format!("{url}?key={api_key}")
}
}
When reqwest encounters a connection error, timeout, or DNS failure, its Error Display implementation includes the full request URL. The handler then returns this error to the proxy user via error_response(502, &format!("upstream error: {e}")) (handler.rs lines 764, 907, 1081), leaking the complete Gemini API key.
Exploit scenario
- A proxy user sends a request routed to a Gemini provider
- The Gemini API is temporarily unreachable (DNS failure, timeout, etc.)
- reqwest returns an error like:
error sending request for url (https://generativelanguage.googleapis.com/...?key=AIzaSy...)
- The full API key is returned to the proxy user in the 502 response
Recommendation
Sanitize error messages before returning to proxy users — strip or redact URLs containing credentials. Alternatively, avoid embedding the key in the URL and use a header-based auth approach for Gemini if supported.
Problem
The Gemini adapter embeds the API key directly in the URL query parameter (
?key=...) atcrates/nyro-core/src/proxy/adapter.rs:92-98:When reqwest encounters a connection error, timeout, or DNS failure, its
ErrorDisplay implementation includes the full request URL. The handler then returns this error to the proxy user viaerror_response(502, &format!("upstream error: {e}"))(handler.rs lines 764, 907, 1081), leaking the complete Gemini API key.Exploit scenario
error sending request for url (https://generativelanguage.googleapis.com/...?key=AIzaSy...)Recommendation
Sanitize error messages before returning to proxy users — strip or redact URLs containing credentials. Alternatively, avoid embedding the key in the URL and use a header-based auth approach for Gemini if supported.