Repository navigation
feat(oidc): HostSessions::is_same_origin for a host's own writes - #190
Merged
Merged
Conversation
A host that admits its session cookie on its own state-changing routes needs to tell its pages from everyone else's. The cookie is SameSite=Lax, so the browser also sends it with requests from other hosts of the same site (two hosts under one registrable domain, e.g. under one tailnet's ts.net name), and Sec-Fetch-Site: same-site does not tell them apart. Only Origin does. is_same_origin is true only when the request holds exactly one Origin, equal byte for byte to the host's origin. A missing Origin is refused: a browser sends it on every fetch other than GET or HEAD and on every form POST. The logout route's own check is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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
Adds
HostSessions::is_same_origin(&HeaderMap) -> bool:trueonly when the request holds exactly oneOriginheader, equal byte for byte to the host's own origin (HostSessions::origin()).A host that admits the session cookie on its own state-changing routes (an API the page calls with the cookie) has to tell its pages from everyone else's. The cookie is
SameSite=Lax, so the browser also sends it with requests from other hosts of the same site: two hosts under one registrable domain, for example two hosts under one tailnet'sts.netname (ts.netis a public suffix, soa.<tailnet>.ts.netandb.<tailnet>.ts.netare one site).Sec-Fetch-Site: same-sitedoes not tell those apart. OnlyOrigindoes.Until now, a host had to copy the check. The logout route's
cross_siteispub(crate), and it is laxer on purpose: it accepts a POST with noOriginwhenSec-Fetch-Siteis notcross-site. This PR leaves that route unchanged.The first user is Pauta (rudaia-hq/pauta), whose page writes through
/api/v1with the session cookie. It keeps a small local copy of this check until this lands.What could be bypassed, and which test shows it is not
Origindiffersis_same_origin_needs_exactly_one_origin_equal_to_the_hosts: "another host of the same site"Origin, onlySec-Fetch-Site: same-originorsame-siteOriginisfalsenullOriginheaders, one of them rightNothing is logged by the new method. No secret is involved.
Checks
cargo fmt --all -- --checkcargo clippy --all-features -- -D warningscargo test -p cli-framework-oidc --features host-session,test-support: 169 passed🤖 Generated with Claude Code