Repository navigation
Conversation
A proxy that ends TLS, such as Railway's edge or the reverse proxy the README recommends, reaches the host over plain HTTP. ReverseProxy's Rewrite drops the X-Forwarded-Proto it sends, so the product builds http:// request URLs and rejects every dashboard batch from an https:// page with 403, failing each read in it. When the configured origin is HTTPS, the proxy now sets X-Forwarded-Proto: https itself. A client's own header is still dropped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #2199.
Behind a proxy that ends TLS, such as Railway's edge or the HTTPS reverse proxy the README recommends, every dashboard batch returns 403. The browser then fails every read in that batch, so any page that loads two or more things at once shows "Unable to complete this request".
The host reaches workerd over plain HTTP, and
ReverseProxy'sRewritedrops theX-Forwarded-Protothe TLS proxy sent.HttpServerRequest.toURLthen buildshttp://<host>, which never matches the browser'sOrigin: https://<host>in the batch same-origin check (batch-host.ts).productProxy Rewrite request.Out.Header.Set("x-executor-client-ip", address) + if publicHTTPS // BETTER_AUTH_URL is https:// + request.Out.Header.Set("X-Forwarded-Proto", "https")The scheme comes from the configured origin, not from the client.
Rewritestill drops a client's ownX-Forwarded-Proto.Evidence
2.0.0-beta.12on a custom HTTPS domain. Over an hour of normal use, none of 33POST /api/dashboard/batchrequests succeeded (28 returned 403).curlwithOrigin: https://<domain>gets 403. WithOrigin: http://<domain>it passes the check (400 for an empty body).2.0.0-beta.12image withBETTER_AUTH_URL=https://executor.test.Origin: https://executor.testpasses the check (400 for an empty body).Origin: http://executor.testgets 403.TestProxyForwardsTheConfiguredOriginsSchemefails without the header line (workerd saw "", want "https") and passes with it.v2at0e9e2c6b3. That build still drops the header.compress_test.go, added since, now passes the new flag toproductProxy.go vet ./...andgo test ./...inapps/hosted/self-host/nativepass.injectRequestHeadersoption sets the same header on the product socket. That stand-in has kept the dashboard working from2.0.0-beta.12through2.0.0-beta.18, which supports this fix in the host.No E2E scenario serves the dashboard behind a TLS proxy. The Go suite runs in
self-host-native.Merge Danger
Door: two-way
Blast Radius: self-host servers with an HTTPS
BETTER_AUTH_URL.Every request to workerd now carries
X-Forwarded-Proto: https. That is true for every origin a browser can sign in on. On such a server, a dashboard opened over plain HTTP (for examplehttp://localhost:4400) now gets 403 on batches. Sign-in already fails there.🤖 Generated with Claude Code