Skip to content

Fix CORS preflight handling in the app dev reverse proxy - #8803

Open
Dylan-GJ wants to merge 1 commit into
Shopify:mainfrom
Dylan-GJ:fix-app-dev-proxy-cors-preflight
Open

Dylan-GJ wants to merge 1 commit into
Shopify:mainfrom
Dylan-GJ:fix-app-dev-proxy-cors-preflight

Conversation

@Dylan-GJ

@Dylan-GJ Dylan-GJ commented Oct 6, 2026

Copy link
Copy Markdown

WHY are these changes introduced?

Fixes #8259

#7164 made the shopify app dev reverse proxy answer CORS OPTIONS requests itself, because some dev servers don't handle them. The response never includes Access-Control-Allow-Credentials, so credentialed cross-origin requests (fetch(..., {credentials: "include"})) fail the preflight even when the app's backend is configured correctly.

Adding the header in the proxy isn't safe: it reflects any Origin, so it would authorize every site. Reverting #7164 (see #8320) would bring back #7324 and #5660 for backends without an OPTIONS handler.

WHAT is this pull request doing?

The proxy now forwards OPTIONS requests to the target app, which decides CORS, credentials included. The proxy only responds itself (same response as before, never with credentials) when the target answers with a 4xx/5xx status or can't be reached.

Hop-by-hop headers are not relayed from the target's preflight response.

How to manually test your changes?

  1. Run shopify app dev with a backend that answers OPTIONS with Access-Control-Allow-Origin and Access-Control-Allow-Credentials: true for a trusted origin. Send a preflight to the tunnel URL:
    curl -i -X OPTIONS -H "Origin: <trusted origin>" -H "Access-Control-Request-Method: POST" <tunnel url>/<path>
    The backend's headers, including credentials, are returned.
  2. Repeat with a backend that has no OPTIONS handler (returns 404/405). The proxy answers with a 204 reflecting the origin, without Access-Control-Allow-Credentials.

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 proxy answered every OPTIONS request itself without
Access-Control-Allow-Credentials, which broke credentialed cross-origin
requests. Preflights now reach the target app, which decides CORS. The proxy
only responds itself, without credentials, when the target answers with an
error status or can't be reached.
@Dylan-GJ

Dylan-GJ commented Oct 6, 2026

Copy link
Copy Markdown
Author

I have signed the CLA!

This branch has not been deployed

No deployments
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.

CORS error on shopify app dev on the cli reverse proxy with credentials: "include"

1 participant