This commit is contained in:
Mateusz Gruszczyński committed 2026-10-11 12:21:26 +02:00
1 parent 0facfe6f5c
commit 95c55da2ee
39 files changed
+715 -151

No files matched your search

+63
View File
@@ -253,6 +253,69 @@
));
}
#[test]
fn admin_origin_diagnostics_redact_non_origin_values() {
let mut headers = HeaderMap::new();
assert_eq!(diagnostic_admin_origin(&headers), "(absent)");
headers.insert(ORIGIN, HeaderValue::from_static("https://panel.example.test"));
assert_eq!(diagnostic_admin_origin(&headers), "https://panel.example.test");
headers.insert(ORIGIN, HeaderValue::from_static("https://user:password@panel.example.test"));
assert_eq!(diagnostic_admin_origin(&headers), "(invalid)");
headers.insert(ORIGIN, HeaderValue::from_static("https://panel.example.test/?token=secret"));
assert_eq!(diagnostic_admin_origin(&headers), "(invalid)");
headers.insert("x-forwarded-host", HeaderValue::from_static("other.example.test"));
assert_eq!(diagnostic_forwarded_header(&headers, "x-forwarded-host", false), "(untrusted)");
assert_eq!(diagnostic_forwarded_header(&headers, "x-forwarded-host", true), "other.example.test");
}
#[tokio::test]
async fn unauthorized_browser_origins_remain_rejected_for_session_checks() {
let (router, store, _dir, secret, _) = fixture().await;
for (origin, fetch_site) in [
(Some("https://attacker.example"), None),
(Some("null"), None),
(None, Some("cross-site")),
] {
let mut request = Request::builder()
.uri("/api/auth/session")
.header("host", "127.0.0.1:9090")
.header("cookie", format!("{}={secret}", auth::COOKIE_NAME));
if let Some(origin) = origin { request = request.header(ORIGIN, origin); }
if let Some(site) = fetch_site { request = request.header("sec-fetch-site", site); }
let response = router.clone().oneshot(request.body(Body::empty()).unwrap()).await.unwrap();
assert_eq!(response.status(), StatusCode::FORBIDDEN);
}
// Origin on an ordinary same-origin GET may be absent, or may match.
for origin in [None, Some("http://127.0.0.1:9090")] {
let mut request = Request::builder()
.uri("/api/auth/session")
.header("host", "127.0.0.1:9090")
.header("cookie", format!("{}={secret}", auth::COOKIE_NAME));
if let Some(origin) = origin { request = request.header(ORIGIN, origin); }
assert_eq!(router.clone().oneshot(request.body(Body::empty()).unwrap()).await.unwrap().status(), StatusCode::OK);
}
store.close().await;
}
#[tokio::test]
async fn invalid_origin_on_document_is_visible_but_still_forbidden() {
let (router, store, _dir, _secret, _) = fixture().await;
let response = router.oneshot(
Request::builder()
.uri("/overview")
.header("host", "127.0.0.1:9090")
.header("origin", "null")
.header("accept", "text/html,application/xhtml+xml")
.body(Body::empty())
.unwrap(),
).await.unwrap();
assert_eq!(response.status(), StatusCode::FORBIDDEN);
assert!(response.headers().get(http::header::CONTENT_TYPE).unwrap().to_str().unwrap().starts_with("text/html"));
let body = axum::body::to_bytes(response.into_body(), 4096).await.unwrap();
assert!(String::from_utf8_lossy(&body).contains("Could not open the panel"));
store.close().await;
}
#[tokio::test]
async fn trusted_https_reverse_proxy_accepts_external_origin_and_refreshes_secure_cookie() {
let mut config = Config::default();