Skip to content

fix(typescript): scope passthrough fetch auth headers to base URL origin#17208

Merged
cadesark merged 2 commits into
mainfrom
devin/1784819317-ts-passthrough-same-origin-auth
Jul 24, 2026
Merged

fix(typescript): scope passthrough fetch auth headers to base URL origin#17208
cadesark merged 2 commits into
mainfrom
devin/1784819317-ts-passthrough-same-origin-auth

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Description

The passthrough client.fetch() escape hatch (makePassthroughRequest) attached the SDK's auth headers to any resolved URL, with no check that the URL targets the configured base URL. Passing an absolute cross-origin URL into client.fetch() therefore leaked the SDK's credentials (e.g. Authorization: Bearer <token>) to that host. This hardens the escape hatch so callers don't have to sanitize URLs themselves.

Reported against a Fern-generated TS SDK (PhenoML/phenoml-ts-sdk#209). Both affected files (makePassthroughRequest.ts, Client.ts) are Fern-generated / core-runtime asIs files, so the fix belongs upstream in the generator's core-utilities where every generated TS SDK picks it up.

Changes Made

  • Gate auth headers on same origin. In makePassthroughRequest.ts, auth headers are attached only when the resolved request URL has the same origin as the configured base URL (or environment):

    if (clientOptions.getAuthHeaders != null && targetsBaseUrl(fullUrl, baseUrl)) { ... }
    
    function targetsBaseUrl(fullUrl: string, baseUrl: string | undefined): boolean {
        if (baseUrl == null) return false;
        try { return new URL(fullUrl).origin === new URL(baseUrl).origin; }
        catch { return false; }
    }

    Relative paths (joined onto baseUrl) and same-origin absolute URLs are unaffected; cross-origin absolute URLs no longer receive the token. Non-auth headers (SDK defaults, init, per-request) are unchanged regardless of origin.

  • Redact credentials in passthrough debug logs. The passthrough debug logs previously logged url: fullUrl verbatim (unlike the main Fetcher, which uses redactUrl()). Extracted redactUrl + SENSITIVE_QUERY_PARAMS from Fetcher.ts into a shared redactUrl.ts (behavior-preserving; Fetcher.ts now imports them) and used it for both passthrough debug log lines.

  • Changelog: added fix entry under generators/typescript/sdk/changes/unreleased/.

  • Regenerated ts-sdk seed snapshots to reflect the template changes (env-only .fern/metadata.json churn reverted).

Testing

  • Unit tests added/updated — new auth header origin scoping suite in makePassthroughRequest.test.ts covering: relative path, same-origin absolute, environment-origin match, cross-origin drop, cross-origin-by-port drop, no-baseUrl drop, and non-auth init headers preserved on cross-origin; plus a debug-log redaction test. Existing auth tests updated to set a matching baseUrl.
  • Manual testing completed — regenerated a TS SDK via seed (--local) and ran the generated suite with vitest: makePassthroughRequest.test.ts 40/40 pass; Fetcher / logging / redacting 68/68 pass (confirming the redactUrl extraction is behavior-preserving). Generated SDK compiles under --isolatedDeclarations.

Link to Devin session: https://app.devin.ai/sessions/994ae83694cb47a5947cbd9d0c11e68d


Open in Devin Review

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

SDK Generation Benchmark Results

Comparing PR branch against median of 5 nightly run(s) on main (latest: 2026-07-23T05:02:46Z).

Full benchmark table (click to expand)
Generator Spec main (generator) main (E2E) PR (generator) Delta
ts-sdk square 177s (n=5) 185s (n=5) 125s -52s (-29.4%)

main (generator): generator-only time via --skip-scripts (includes Docker image build, container startup, IR parsing, and code generation — this is the same Docker-based flow customers use via fern generate). main (E2E): full customer-observable time including build/test scripts (nightly baseline, informational). Delta is computed against generator-only baseline.
⚠️ = generation exited with a non-zero exit code (timing may not reflect a successful run).
Baseline from nightly runs on main (latest: 2026-07-23T05:02:46Z). Trigger benchmark-baseline to refresh.
Last updated: 2026-07-23 17:54 UTC

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@cadesark
cadesark merged commit 67c55f2 into main Jul 24, 2026
74 checks passed
@cadesark
cadesark deleted the devin/1784819317-ts-passthrough-same-origin-auth branch July 24, 2026 14: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.

2 participants