fix(server): let platform auto-detection survive an invalid PUBLIC_ORIGIN - #328
Open
lovepixel-git wants to merge 1 commit into
Open
fix(server): let platform auto-detection survive an invalid PUBLIC_ORIGIN#328lovepixel-git wants to merge 1 commit into
lovepixel-git wants to merge 1 commit into
Conversation
…IGIN
`resolvePublicOrigins` tested the precedence gate against the raw CSV
list but returned the normalized one, so a `PUBLIC_ORIGIN` whose entries
all fail to parse claimed precedence and then resolved to `[]`:
resolvePublicOrigins({ PUBLIC_ORIGIN: 'https://',
RAILWAY_PUBLIC_DOMAIN: 'app.up.railway.app' })
-> []
resolvePublicOrigins({ RAILWAY_PUBLIC_DOMAIN: 'app.up.railway.app' })
-> ['https://app.up.railway.app']
Setting the variable badly was strictly worse than leaving it unset:
platform auto-detection was suppressed, publicOrigins came back empty,
and the CSRF check fell through to its inbound-Host fallback.
Normalizing before the gate fixes it. A list with at least one parseable
entry still wins outright, and invalid entries in a partly valid list are
still dropped rather than promoting auto-detection.
Refs CoreBunch#185
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.
The defect
resolvePublicOriginstests the precedence gate against the raw CSV list but returns the normalized one. APUBLIC_ORIGINwhose entries all fail to parse therefore claims precedence and then resolves to[], silently suppressing platform auto-detection:Setting the variable badly is strictly worse than leaving it unset.
normalizeOriginreturns null for'https://'becausenew URL('https://')throws, so the list empties out after the gate has already been passed.Downstream, an empty
publicOriginsputs the CSRF check on its inbound-Hostfallback, which derives the scheme fromreq.url. Behind a TLS-terminating edge that yieldshttp://…against a browserOriginofhttps://…, and the request is rejected.Change
Normalize before the gate rather than after. One function, four lines.
A list with at least one parseable entry still wins outright, and invalid entries inside a partly valid list are still dropped rather than promoting auto-detection. Both existing tests that pin those behaviors pass unchanged, which is the signal that the diff is narrow.
A design call that is yours, not mine
Given a
PUBLIC_ORIGINwhere every entry is unparseable, there are three defensible behaviors:I picked 1 because it makes the function match its own documented precedence, and because it is the smallest change. But this is your CSRF code from #14 and you wrote the existing test that deliberately drops invalid entries, so you may well prefer 2 — a container that refuses to start is arguably better operator feedback than one that quietly resolves to something else. Say the word and I will rewrite it as a boot-time throw, or add a warning alongside the fallthrough.
On #185
I am referencing that issue as motivation, not claiming it as a fix. The code defect above is proven independently. Whether it explains that particular Railway report is a hypothesis: it fits (a template rendering
https://${{RAILWAY_PUBLIC_DOMAIN}}before the domain is provisioned collapses to exactlyhttps://), but I cannot verify Railway's variable-resolution timing, and ifRAILWAY_PUBLIC_DOMAINwas also empty on that boot the fallthrough would have returned[]anyway. Treat this as a standalone correctness fix.Tests
Three cases added to the existing
describe('resolvePublicOrigins')block. Two of them fail on currentmainand pass here; the third (invalidPUBLIC_ORIGINwith no platform var still yields[]) passes either way and is there to pin the non-over-correction.bunx tsc -bexit 0bun run lintcleanbun test6533 pass, 1 failThat single failure is
Bundle size budgets > ContentPage-*.js, 90043 B against a 90000 B budget. Pre-existing and unrelated: it reproduces byte-identically on untouchedmainand only surfaces oncedist/exists.I deliberately did not touch
expectedOrigin's scheme handling.server/auth/security.tsdocuments that forwarded headers are not consulted for CSRF, and that is the point of the design.