[rust-server] Restrict from_headers matches to the intended auth scheme - #24607
Open
twistali wants to merge 1 commit into
Open
[rust-server] Restrict from_headers matches to the intended auth scheme#24607twistali wants to merge 1 commit into
twistali wants to merge 1 commit into
Conversation
Contributor
|
This fixes the issue here, but the untyped from_headers still seems like a footgun for anyone hand-rolling swagger-rs 7.x. Worth an issue against Metaswitch/swagger-rs too? |
Contributor
|
@wing328 circle CI looks unrelated. Are there issues occurring on that CI system? |
Contributor
|
Two potential testing gaps to consider. There's no fixture proving Basic+Bearer coexist without swallowing each other (only OAuth+Basic is tested), and the assertions are string-exact rather than runtime tested. A request-level test through AddContext::call would prove the actual fallthrough behavior as |
Member
|
for circleci failures, please ignore those for the time being |
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.
Fixes #24095
Problem
The
rust-servercontext.mustachetemplate emits one block per security scheme, each doing an earlyreturnon match. TheAuthorization-header blocks callswagger::auth::from_headers(headers)and bind the result unconditionally:Since swagger-rs 7,
from_headersis no longer scheme-typed. It returnsOption<AuthData>and matches either scheme (swagger-7.0.1src/auth.rs:216):So a
Basic-only block swallowsBearerrequests (and vice versa) and returns immediately, making every later security scheme block unreachable — including in-headerapiKeyblocks.Impact: for any spec where an
Authorization-header scheme precedes an in-headerapiKeyscheme, a request carryingAuthorization: Bearer …is authorized via the wrong scheme and the API key / client certificate is never evaluated. Where the mismatched path has a permissive fallback (e.g.AllowAllAuthenticatorwhen OAuth is unconfigured) this is a silent authorization bypass. This is a regression from the swagger 5/6 typedfrom_headers::<Basic>(headers)form.Fix
Option B from the bug ticket — restrict each block's pattern to the variant it was generated for, so a non-matching header falls through to the next block instead of being consumed:
AuthDatais already imported by the template, so no new imports are needed, and no change to swagger-rs is required — this fixes every 7.x consumer immediately.Note this fixes
isOAuthandisBasicBeareras well as the reportedisBasicBasic: aBasicheader could equally be swallowed by a Bearer/OAuth block.Behaviour change
Worth calling out explicitly: on an API declaring only Basic auth, a request with
Authorization: Bearer …previously reached the authenticator asAuthData::Bearer; it now falls through tocontext.push(None::<AuthData>)and is treated as unauthenticated (and symmetrically for aBasicheader on a Bearer/OAuth-only API). That is the intended security fix, but it is a semantic change for anyone relying on the permissive behaviour. Happy to retarget if maintainers consider this breaking.Not addressed (pre-existing, out of scope): an in-header
apiKeyscheme whose header name is literallyAuthorizationwould still collide.Changes
modules/openapi-generator/src/main/resources/rust-server/context.mustache— scheme-restricted patterns for theisBasicBasic,isBasicBearerandisOAuthblocks.RustServerCodegenTest.testAuthSchemeBlocksOnlyMatchTheirOwnScheme— new regression test asserting both the correct forms and, viaassertFileNotContains, the absence of the unrestricted forms; also asserts the in-headerapiKeyblock is still generated.openapi-v3,petstore-with-fake-endpoints-models-for-testing,ping-bearer-auth.Testing
./mvnw clean package— BUILD SUCCESS, full test suite green../bin/generate-samples.sh bin/configs/rust-server*.yaml— 7/7 generators succeeded, no sample drift.mvn -pl modules/openapi-generator -am test -Dtest=RustServerCodegenTest— 7/7 pass.context.mustachealone makes it fail withdoes not contain line [if let Some(bearer @ AuthData::Bearer(..)) = …].cargo check --all-featureson the regeneratedpetstore-with-fake-endpoints-models-for-testingsample compiles clean.rust-serversample retains an unrestricted= swagger::auth::from_headers(headers), and thatcontext.mustacheis the only template referencingfrom_headers.CC @frol @farcaller @richardwhiuk @paladinzh @jacob-pro @dsteeley
PR checklist
Commit all changed files.
This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example
./bin/generate-samples.sh bin/configs/java*.IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
Summary by cubic
Restricts
rust-serverauth handling to match only the intended scheme (Basic vs Bearer) so cross-scheme matches no longer short-circuit later auth blocks like headerapiKey(fixes #24095).Bug Fixes
context.mustache:AuthData::Basic(..)for Basic andAuthData::Bearer(..)for Bearer/OAuth.apiKey.Migration
Authorizationheaders on single-scheme APIs now fall through as unauthenticated.swagger-rs7.x generated servers.Written for commit ddd272f. Summary will update on new commits.