Skip to content

Send OAuth token request params in POST body instead of URL#7372

Merged
isaacroldan merged 1 commit intomainfrom
river/fix-oauth-token-in-query-string
Apr 22, 2026
Merged

Send OAuth token request params in POST body instead of URL#7372
isaacroldan merged 1 commit intomainfrom
river/fix-oauth-token-in-query-string

Conversation

@isaacroldan
Copy link
Copy Markdown
Contributor

@isaacroldan isaacroldan commented Apr 22, 2026

The cli-kit tokenRequest() helper was placing all OAuth parameters (subject_token, refresh_token, device_code, client_id, etc.) into the URL query string of POST requests to /oauth/token.

RFC 6749 specifies that these parameters are sent in the request body as application/x-www-form-urlencoded data, and putting credentials in URLs causes them to leak into verbose CLI debug output, HTTP access logs, proxies, and anywhere else URLs are recorded.

This commit:

  • Moves the OAuth parameters from the URL query string into the POST request body (form-encoded).
  • Expands sanitizeURL to mask all sensitive OAuth parameter names (access_token, refresh_token, id_token, subject_token, actor_token, device_code, client_secret, code) so that any URL that ever carries one of these values in the future is still redacted as defence in depth.
  • Updates tests to assert the new behaviour and adds coverage for every sanitized parameter.

WHY are these changes introduced?

Fixes #0000

WHAT is this pull request doing?

How to test your changes?

Using the snapshot:
shopify auth logout then shopify auth login

Post-release steps

Checklist

  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've considered possible documentation changes
  • I've considered analytics changes to measure impact
  • The change is user-facing — I've identified the correct bump type (patch for bug fixes · minor for new features · major for breaking changes) and added a changeset with pnpm changeset add

The cli-kit `tokenRequest()` helper was placing all OAuth parameters
(`subject_token`, `refresh_token`, `device_code`, `client_id`, etc.)
into the URL query string of POST requests to `/oauth/token`.

RFC 6749 specifies that these parameters are sent in the request body as
`application/x-www-form-urlencoded` data, and putting credentials in
URLs causes them to leak into verbose CLI debug output, HTTP access logs,
proxies, and anywhere else URLs are recorded.

This commit:

- Moves the OAuth parameters from the URL query string into the POST
  request body (form-encoded).
- Expands `sanitizeURL` to mask all sensitive OAuth parameter names
  (`access_token`, `refresh_token`, `id_token`, `subject_token`,
  `actor_token`, `device_code`, `client_secret`, `code`) so that any
  URL that ever carries one of these values in the future is still
  redacted as defence in depth.
- Updates tests to assert the new behaviour and adds coverage for every
  sanitized parameter.

Reported through Shopify's bug bounty programme (report #3686978).

Requested by Josh Bregar <josh.bregar@shopify.com>

Co-authored-by: Josh Bregar <josh.bregar@shopify.com>
@shopify-river shopify-river Bot force-pushed the river/fix-oauth-token-in-query-string branch from 089dcf7 to 92b092a Compare April 22, 2026 14:35
@isaacroldan isaacroldan marked this pull request as ready for review April 22, 2026 14:39
@isaacroldan isaacroldan requested a review from a team as a code owner April 22, 2026 14:39
Copilot AI review requested due to automatic review settings April 22, 2026 14:39
@isaacroldan
Copy link
Copy Markdown
Contributor Author

/snapit

@github-actions
Copy link
Copy Markdown
Contributor

🫰✨ Thanks @isaacroldan! Your snapshot has been published to npm.

Test the snapshot by installing your package globally:

pnpm i -g --@shopify:registry=https://registry.npmjs.org @shopify/cli@0.0.0-snapshot-20260422144132

Caution

After installing, validate the version by running shopify version in your terminal.
If the versions don't match, you might have multiple global instances installed.
Use which shopify to find out which one you are running and uninstall it.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the cli-kit OAuth token exchange flow to avoid leaking credentials by moving OAuth parameters from the URL query string into a form-encoded POST body, and expands URL sanitization to redact a broader set of sensitive OAuth-related query parameters.

Changes:

  • Send OAuth token request parameters as application/x-www-form-urlencoded POST body data instead of URL query params.
  • Expand sanitizeURL to redact additional sensitive OAuth parameter names.
  • Update/add tests to assert body-based parameter sending and to cover sanitization for each sensitive parameter.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
packages/cli-kit/src/private/node/session/exchange.ts Moves /oauth/token parameters into POST body with form encoding and explicit content type.
packages/cli-kit/src/private/node/session/exchange.test.ts Updates token-exchange tests to assert no query params and validate form body + headers.
packages/cli-kit/src/private/node/api/urls.ts Reworks sanitizeURL to redact a list of sensitive OAuth query parameters.
packages/cli-kit/src/private/node/api/urls.test.ts Adds parameterized tests to ensure every sensitive query param is sanitized.
Comments suppressed due to low confidence (1)

packages/cli-kit/src/private/node/api/urls.ts:20

  • The JSDoc for sanitizeURL has an incorrect @param description (HTTP headers). This function accepts a URL string; updating the doc helps avoid confusion for callers and keeps generated docs accurate.
/**
 * Removes the sensitive data from the url and outputs them as a string.
 * @param url - HTTP headers.
 * @returns A sanitized version of the url as a string.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/cli-kit/src/private/node/api/urls.test.ts
@isaacroldan isaacroldan added this pull request to the merge queue Apr 22, 2026
Merged via the queue into main with commit d5b7839 Apr 22, 2026
30 checks passed
@isaacroldan isaacroldan deleted the river/fix-oauth-token-in-query-string branch April 22, 2026 15:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants