fix(api): keep configured headers on their own origin - #196
Merged
tina4stack merged 1 commit intoOct 3, 2026
Merged
tina4stack merged 1 commit into
tina4stack merged 1 commit into
Conversation
A header configured on the client (constructor headers, add_headers) can carry a credential under any name, such as X-Api-Key. Only Authorization and Cookie were held back from another origin, so every other configured header went to an absolute off-origin target and onto a cross-origin redirect hop, and a per-call header followed a cross-origin redirect too. Configured headers are now bound to the base origin like the token: an absolute target on another origin gets only content-negotiation headers (User-Agent, Accept, Accept-Encoding, Accept-Language, Content-Type, Content-Length), and a cross-origin redirect hop carries only those. A client with no base keeps sending its headers to the URL each call names, and drops them on a redirect to another origin. Signed-off-by: Michael <[email protected]>
Contributor
Author
|
I have read the Tina4 Contributor Licence Agreement and I agree to it. |
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
Apiclient sends headers configured on it (constructor headers,add_headers/addHeaders) to other origins. A header can carry a credential under any name, such asX-Api-Key, but onlyAuthorizationandCookiewere held back from another origin. So a configuredX-Api-Keywent to an absolute off-origin URL and onto a redirect to another host, and a per-call header followed a cross-origin redirect too. This builds on theAuthorization/Cookiefix in GHSA-m4rj-2p76-3p8v.Change. Configured headers are now bound to the base origin, like the token. An absolute target on another origin, and a cross-origin redirect hop, carry only
User-Agent,Accept,Accept-Encoding,Accept-Language,Content-TypeandContent-Length. A client with no base URL keeps sending its headers to the URL each call names, and drops them on a redirect to another origin. The allowlist is the same six names, case-insensitive, in all four ports.Checked. A 45-case matrix against real listeners (301/302/303/307/308 with GET and POST; host, scheme and port changes; A to B to A; upper-case, protocol-relative, userinfo and backslash targets; a base with a path; no base; upload, download and stream; per-call headers; the cookie jar). On
3.13.144the leak shows in 21 to 27 of them per port; with this change it shows in none, and every same-origin and no-base control keeps its header.Tests.
tests/test_api_cross_origin_token.pygains 4 cases; 4 of its 16 fail onv3, all pass here. Python never follows a 307/308 POST (urllib), as before. Each of the three parts of the fix (redirect keep-list, initial-target binding, no-base guard) was broken on its own in a copy, and the file went red every time.Suite. Failing set identical to
v3.tests/test_swagger_contract.pyis skipped on both becauseopenapi_spec_validatoris not installed in the venv.Metrics.
tina4 metrics --fail-on-regression(3.8.95): no regression.Behaviour changes.
Range,If-None-MatchandX-Request-Id.X-Api-Keybehind one now gets a 401 instead of the key being forwarded. requests, curl and Go only strip auth and cookie headers, so this is stricter than all three.Docs.
docs/python/21-api-client.md:106,130say headers are 'sent with every request'; a docs PR updates them.Parity. Same fix in tina4-php, tina4-python, tina4-ruby and tina4-nodejs.