diff --git a/crates/oe-httpapi/src/lib.rs b/crates/oe-httpapi/src/lib.rs index ddcbb42..6ac0b7a 100644 --- a/crates/oe-httpapi/src/lib.rs +++ b/crates/oe-httpapi/src/lib.rs @@ -64,9 +64,13 @@ pub fn router(opts: Options) -> Router { .layer(tower_http::trace::TraceLayer::new_for_http()); if let Some(origin) = opts.cors_allowed_origin.as_deref() { if let Ok(origin) = axum::http::HeaderValue::from_str(origin) { + // `allow_origin(HeaderValue)` (AllowOrigin::exact) renverrait cette + // valeur sur TOUTE requête, quelle que soit son origine réelle — + // AllowOrigin::list ne la reflète que si l'en-tête Origin de la + // requête correspond exactement, et l'omet sinon. router = router.layer( tower_http::cors::CorsLayer::new() - .allow_origin(origin) + .allow_origin(tower_http::cors::AllowOrigin::list([origin])) .allow_methods([axum::http::Method::GET, axum::http::Method::POST]) .allow_headers([axum::http::header::CONTENT_TYPE]), ); diff --git a/crates/oe-httpapi/tests/end_to_end.rs b/crates/oe-httpapi/tests/end_to_end.rs index 7637aa6..6d8b4f9 100644 --- a/crates/oe-httpapi/tests/end_to_end.rs +++ b/crates/oe-httpapi/tests/end_to_end.rs @@ -212,4 +212,16 @@ async fn cors_header_present_only_when_configured() { resp.headers().get("access-control-allow-origin").unwrap(), "https://demo.open-eidas.eu" ); + + // Une origine différente, elle, ne doit PAS recevoir l'en-tête : sinon + // `AllowOrigin::exact` renverrait cette même valeur à n'importe qui + // (fuite d'information sur la configuration, pas une vraie restriction + // par origine — voir la revue du commit qui a introduit ce test). + let resp = reqwest::Client::new() + .get(format!("http://{addr}/api/v1/policy")) + .header("Origin", "https://evil.example") + .send() + .await + .unwrap(); + assert!(resp.headers().get("access-control-allow-origin").is_none()); }