This commit is contained in:
Mateusz Gruszczyński committed 2026-10-11 13:56:30 +02:00
1 parent 95c55da2ee
commit d942c1a35d
42 files changed
+1265 -109

No files matched your search

+29 -7
View File
@@ -117,17 +117,39 @@ async fn guard(State(state): State<Arc<App>>, mut request: Request, next: Next)
let headers = request.headers();
let trusted_host = trusted_admin_proxy(&state, peer);
let trusted_proto = trusted_admin_forwarded_proto(&state, peer);
let scheme = match external_admin_scheme(&state, headers, peer, transport) {
Ok(value) => value,
Err(()) => {
return invalid_admin_origin(&request, "external_scheme", None, None, trusted_host, trusted_proto);
}
// Pinned browser origin is panel-only. Certificate automation using API
// credentials keeps the original forwarding/TLS authorization semantics.
let automation_credentials = headers.contains_key(CERTIFICATE_API_KEY_HEADER)
|| (headers.contains_key(AUTHORIZATION)
&& certificate_api_operation(request.method(), request.uri().path()).is_some());
let pinned_authority_result = if automation_credentials {
Ok(None)
} else {
configured_admin_public_authority(&state, headers, peer, &raw_host, transport)
};
let external_authority =
match external_admin_authority(&state, headers, peer, &raw_host, scheme == "https") {
let pinned_authority = match pinned_authority_result {
Ok(value) => value,
Err(()) => return invalid_admin_origin(&request, "pinned_origin_mismatch", Some("https"),
state.active_administration.public_origin.as_deref().and_then(|value| value.strip_prefix("https://")),
trusted_host, trusted_proto),
};
let (scheme, external_authority) = if let Some(authority) = pinned_authority {
// HTTPS is a trusted, administrator-pinned identity here. Do not select
// any list element of an ambiguous forwarded-proto chain.
("https", authority)
} else {
let scheme = match external_admin_scheme(&state, headers, peer, transport) {
Ok(value) => value,
Err(()) => {
return invalid_admin_origin(&request, "external_scheme", None, None, trusted_host, trusted_proto);
}
};
let authority = match external_admin_authority(&state, headers, peer, &raw_host, scheme == "https") {
Ok(value) => value,
Err(()) => return secure(reject(StatusCode::FORBIDDEN, "auth.invalid_host")),
};
(scheme, authority)
};
if headers.get_all(ORIGIN).iter().count() > 1
|| headers.get(ORIGIN).is_some_and(|h| {
h.to_str()