Skip to content

Restrict Google Discovery bundle URLs#1105

Closed
RhysSullivan wants to merge 1 commit into
fix/graphql-hosted-egress-guardfrom
fix/google-discovery-url-allowlist
Closed

Restrict Google Discovery bundle URLs#1105
RhysSullivan wants to merge 1 commit into
fix/graphql-hosted-egress-guardfrom
fix/google-discovery-url-allowlist

Conversation

@RhysSullivan

Copy link
Copy Markdown
Owner

What changed

  • Canonicalize Google Discovery URLs before fetch, storage, and detection.
  • Allow only HTTPS www.googleapis.com/discovery/v1/apis/.../rest and documented {service}.googleapis.com/$discovery/rest?version=... endpoints.
  • Reject lookalike hosts, userinfo, non-HTTPS schemes, and unexpected query parameters before making bundle fetches.
  • Keep preset audience warnings aligned with canonical Discovery URLs.

Why

The Google bundle flow accepted caller-supplied Discovery URLs and only checked for broad googleapis.com strings, which allowed lookalike hosts and untrusted fetch targets.

Validation

  • bun --bun vitest run src/sdk/discovery.test.ts src/sdk/plugin.test.ts src/sdk/product-picker-scopes.test.ts from packages/plugins/google
  • bun run --cwd packages/plugins/google typecheck
  • git diff --check

Stack

Base: fix/openapi-hosted-origin-guard

Previous: #1104

Next: fix/microsoft-graph-url-allowlist

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 23, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
executor-marketing f275c2c Commit Preview URL

Branch Preview URL
Jun 23 2026, 06:13 PM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 23, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
executor-cloud f275c2c Jun 23 2026, 06:16 PM

@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Cloudflare preview

Torn down — the PR is closed.

@pkg-pr-new

pkg-pr-new Bot commented Jun 23, 2026

Copy link
Copy Markdown

Open in StackBlitz

@executor-js/cli

npm i https://pkg.pr.new/@executor-js/cli@1105

@executor-js/config

npm i https://pkg.pr.new/@executor-js/config@1105

@executor-js/execution

npm i https://pkg.pr.new/@executor-js/execution@1105

@executor-js/sdk

npm i https://pkg.pr.new/@executor-js/sdk@1105

@executor-js/codemode-core

npm i https://pkg.pr.new/@executor-js/codemode-core@1105

@executor-js/runtime-quickjs

npm i https://pkg.pr.new/@executor-js/runtime-quickjs@1105

@executor-js/plugin-file-secrets

npm i https://pkg.pr.new/@executor-js/plugin-file-secrets@1105

@executor-js/plugin-graphql

npm i https://pkg.pr.new/@executor-js/plugin-graphql@1105

@executor-js/plugin-keychain

npm i https://pkg.pr.new/@executor-js/plugin-keychain@1105

@executor-js/plugin-mcp

npm i https://pkg.pr.new/@executor-js/plugin-mcp@1105

@executor-js/plugin-onepassword

npm i https://pkg.pr.new/@executor-js/plugin-onepassword@1105

@executor-js/plugin-openapi

npm i https://pkg.pr.new/@executor-js/plugin-openapi@1105

executor

npm i https://pkg.pr.new/executor@1105

commit: 54782a5

@RhysSullivan RhysSullivan force-pushed the fix/openapi-hosted-origin-guard branch from f46a78f to e747baa Compare June 23, 2026 17:00
@RhysSullivan RhysSullivan force-pushed the fix/google-discovery-url-allowlist branch 2 times, most recently from be395f6 to 94c590f Compare June 23, 2026 17:02
@RhysSullivan RhysSullivan force-pushed the fix/openapi-hosted-origin-guard branch from e747baa to 8f3481d Compare June 23, 2026 17:07
@RhysSullivan RhysSullivan force-pushed the fix/google-discovery-url-allowlist branch from 94c590f to 7a69015 Compare June 23, 2026 17:08
@RhysSullivan RhysSullivan force-pushed the fix/openapi-hosted-origin-guard branch from 8f3481d to 9e508f9 Compare June 23, 2026 17:36
@RhysSullivan RhysSullivan force-pushed the fix/google-discovery-url-allowlist branch from 7a69015 to e9aff2c Compare June 23, 2026 17:36
@RhysSullivan RhysSullivan changed the base branch from fix/openapi-hosted-origin-guard to fix/graphql-hosted-egress-guard June 23, 2026 18:01
@RhysSullivan RhysSullivan force-pushed the fix/google-discovery-url-allowlist branch from e9aff2c to 54782a5 Compare June 23, 2026 18:01
@RhysSullivan RhysSullivan marked this pull request as ready for review June 23, 2026 18:02
@greptile-apps

greptile-apps Bot commented Jun 23, 2026

Copy link
Copy Markdown

Greptile Summary

This PR hardens the Google Discovery bundle flow by replacing broad googleapis.com substring checks with a strict two-branch allowlist: www.googleapis.com/discovery/v1/apis/{service}/{version}/rest and {service}.googleapis.com/$discovery/rest?version=…. Both branches canonicalize to the same www.googleapis.com form, so all three entry points (fetchGoogleDiscoveryDocument, uniqueUrls, detect) now operate exclusively on validated canonical URLs.

  • normalizeGoogleDiscoveryUrl (new public export) rejects lookalike hosts, non-HTTPS schemes, userinfo, hash fragments, unexpected query parameters, and any pathname that doesn't match a known Discovery pattern before any network call is made.
  • uniqueUrls now deduplicates by canonical URL rather than raw string, so chat.googleapis.com/$discovery/rest?version=v1 and its www.googleapis.com equivalent correctly collapse to one entry.
  • presets.ts wires normalizeGoogleDiscoveryUrl into the preset-URL normalization so $discovery/rest-style preset URLs (forms, keep, admin, cloudresourcemanager) resolve to canonical form for audience-warning lookups.

Confidence Score: 5/5

Safe to merge — the change adds defence-in-depth URL allowlisting with no regressions to the existing fetch or detect flows.

All three entry points now validate and canonicalize Discovery URLs before any network activity. The two-branch normalization is idempotent (canonical URLs round-trip cleanly), preset lookups and audience warnings are correctly updated, and the new tests exercise both the happy path and lookalike-host rejection. No pre-existing flows are broken, and the new guard is consistently applied.

No files require special attention; discovery.ts carries the most logic and has solid test coverage.

Important Files Changed

Filename Overview
packages/plugins/google/src/sdk/discovery.ts Core URL validation logic: exports normalizeGoogleDiscoveryUrl and isGoogleDiscoveryUrl; adds strict allowlist for HTTPS googleapis.com endpoints; preflight check in fetchGoogleDiscoveryDocument blocks fetches to non-canonical hosts.
packages/plugins/google/src/sdk/plugin.ts Switches uniqueUrls from a trim/length filter to normalizeGoogleDiscoveryUrl; replaces isGoogleDiscoveryUrl with normalizeGoogleDiscoveryUrl in detect so the canonical URL is used throughout the add/detect flows.
packages/plugins/google/src/sdk/presets.ts normalizeGooglePresetUrl now tries normalizeGoogleDiscoveryUrl first, ensuring preset URLs stored in $discovery/rest format (forms, keep, admin, cloudresourcemanager) are canonicalized before audience-warning lookups.
packages/plugins/google/src/sdk/discovery.test.ts Adds unit tests for normalizeGoogleDiscoveryUrl (trailing-slash stripping, service subdomain → canonical conversion) and isGoogleDiscoveryUrl (lookalike host, HTTP, extra query params, userinfo rejection).
packages/plugins/google/src/sdk/plugin.test.ts Adds integration test that verifies no HTTP requests are made when all supplied URLs are lookalike hosts; confirms the failure exits cleanly without touching the mocked HttpClient.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Caller-supplied URL] --> B[normalizeGoogleDiscoveryUrl]
    B --> C{protocol === https:\nno userinfo/hash?}
    C -->|No| D[return null]
    C -->|Yes| E{host === www.googleapis.com?}
    E -->|Yes| F{any search params?}
    F -->|Yes| D
    F -->|No| G{pathname matches\n/discovery/v1/apis/service/version/rest?}
    G -->|No| D
    G -->|Yes| H[canonical www.googleapis.com URL]
    E -->|No| I{serviceFromGoogleApisHost\nhost.endsWith .googleapis.com\nno subdots, valid chars}
    I -->|null| D
    I -->|service| J{pathname /$discovery/rest\nonly version= param\nversion passes RE?}
    J -->|No| D
    J -->|Yes| H
    H --> K[uniqueUrls dedup by canonical form]
    H --> L[fetchGoogleDiscoveryDocument\npreflight re-validates]
    H --> M[detect: store canonical endpoint]
    H --> N[presets: audience-warning lookup]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[Caller-supplied URL] --> B[normalizeGoogleDiscoveryUrl]
    B --> C{protocol === https:\nno userinfo/hash?}
    C -->|No| D[return null]
    C -->|Yes| E{host === www.googleapis.com?}
    E -->|Yes| F{any search params?}
    F -->|Yes| D
    F -->|No| G{pathname matches\n/discovery/v1/apis/service/version/rest?}
    G -->|No| D
    G -->|Yes| H[canonical www.googleapis.com URL]
    E -->|No| I{serviceFromGoogleApisHost\nhost.endsWith .googleapis.com\nno subdots, valid chars}
    I -->|null| D
    I -->|service| J{pathname /$discovery/rest\nonly version= param\nversion passes RE?}
    J -->|No| D
    J -->|Yes| H
    H --> K[uniqueUrls dedup by canonical form]
    H --> L[fetchGoogleDiscoveryDocument\npreflight re-validates]
    H --> M[detect: store canonical endpoint]
    H --> N[presets: audience-warning lookup]
Loading

Reviews (2): Last reviewed commit: "Restrict Google Discovery bundle URLs" | Re-trigger Greptile

Comment thread packages/plugins/google/src/sdk/discovery.ts
Comment thread packages/plugins/google/src/sdk/plugin.ts
@RhysSullivan RhysSullivan force-pushed the fix/google-discovery-url-allowlist branch from 54782a5 to f275c2c Compare June 23, 2026 18:11
@RhysSullivan RhysSullivan force-pushed the fix/graphql-hosted-egress-guard branch from f2e5bc2 to 5865d0c Compare June 23, 2026 18:11
@RhysSullivan

Copy link
Copy Markdown
Owner Author

Superseded by batch merge #1106.

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