Skip to content

Fix SSRF / credential exfiltration via api_endpoint (b/565094291) - #644

Draft
erinlimbogoogle wants to merge 1 commit into
GoogleCloudPlatform:mainfrom
erinlimbogoogle:fix/querydata-endpoint-ssrf
Draft

erinlimbogoogle wants to merge 1 commit into
GoogleCloudPlatform:mainfrom
erinlimbogoogle:fix/querydata-endpoint-ssrf

Conversation

@erinlimbogoogle

Copy link
Copy Markdown
Collaborator

Fix SSRF / credential exfiltration via api_endpoint (b/565094291)

📌 Summary

Property Details
Issue ID b/565094291
Component QueryDataAPIGenerator
Vulnerability Server-Side Request Forgery (SSRF) / Credential Exfiltration
Mitigation Early endpoint allowlist validation in __init__ prior to client creation

⚠️ Problem & Security Impact

QueryDataAPIGenerator previously accepted an arbitrary api_endpoint from client-supplied model configurations (EvalConfig). The server then transmitted its Application Default Credentials (ADC) to that endpoint:

Transport Path Implementation Mechanism
gRPC Passed directly via DataChatServiceClient(client_options=...)
REST Dispatched via Authorization: Bearer <token> request header

Impact: A caller submitting an EvalConfig could steer the server's access token to an attacker-controlled host.


💡 Solution & Validation Rules

The api_endpoint parameter is now validated in __init__ before initializing the service client. Hostnames must strictly match an allowlist of bare Google domain patterns:

Host Category Pattern / Allowlist Rule Action
Production Bare geminidataanalytics.googleapis.com and *-/* prefixes Allowed
Test Environments *.sandbox.googleapis.com Allowed
Default Settings Default endpoint configuration Unchanged
Invalid Inputs Schemes (https://), paths, ports (:443), userinfo, or suffix lookalikes Raises ValueError

✅ Test Coverage

Added 4 comprehensive unit tests:

Test Suite Verification Scope
Host Allowlist Validates accepted bare production and sandbox hostnames
Normalization Ensures valid hostnames normalize predictably
Rejection Scenarios Tests ~20 adversarial inputs (schemes, paths, ports, suffix spoofs) raise ValueError
Credential Guard (REST) Verifies the REST path never fetches a token or issues a request for rejected hosts

…owlist

QueryDataAPIGenerator read api_endpoint from the client-supplied model
config without validation and then (a) passed it to DataChatServiceClient,
which attaches ADC credentials, and (b) on the REST path interpolated it
into the request URL and sent the server's ADC bearer token in the
Authorization header. A caller able to submit an EvalConfig could set
api_endpoint to a host they control and receive the server's credentials.

Validate api_endpoint in __init__, before the client is constructed, so
both the gRPC and REST paths only ever target an allowlisted host:

  geminidataanalytics.googleapis.com
  <prefix>-geminidataanalytics.googleapis.com   (autopush/staging)
  <label>.geminidataanalytics.googleapis.com    (regional)
  <label>.sandbox.googleapis.com                (test environments)

Only bare hostnames are accepted. Schemes, paths, ports, userinfo and
suffix lookalikes raise ValueError. Values are trimmed and lowercased.

Fixes b/565094291
@erinlimbogoogle
erinlimbogoogle force-pushed the fix/querydata-endpoint-ssrf branch from adaef30 to 624070b Compare October 3, 2026 16:07
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.

1 participant