diff --git a/apps/gateway/Cargo.toml b/apps/gateway/Cargo.toml index 4b55ae9..985bacb 100644 --- a/apps/gateway/Cargo.toml +++ b/apps/gateway/Cargo.toml @@ -8,7 +8,7 @@ axum = { workspace = true } tokio = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } -tower-http = { version = "0.6", features = ["cors"] } +tower-http = { version = "0.6", features = ["cors", "set-header"] } tracing = { workspace = true } tracing-subscriber = { workspace = true } reqwest = { version = "0.12", features = ["json", "stream"] } diff --git a/apps/gateway/src/main.rs b/apps/gateway/src/main.rs index feddde6..54cf951 100644 --- a/apps/gateway/src/main.rs +++ b/apps/gateway/src/main.rs @@ -9,6 +9,7 @@ use axum::{ }; use std::net::SocketAddr; use tower_http::cors::{AllowHeaders, AllowOrigin, CorsLayer}; +use tower_http::set_header::SetResponseHeaderLayer; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; #[derive(Clone)] @@ -263,6 +264,26 @@ async fn main() { .route("/api/{*path}", any(proxy_handler)) .route("/health", any(|| async { "Gateway OK" })) .layer(cors) + .layer(SetResponseHeaderLayer::if_not_present( + axum::http::header::X_FRAME_OPTIONS, + HeaderValue::from_static("DENY"), + )) + .layer(SetResponseHeaderLayer::if_not_present( + axum::http::header::X_CONTENT_TYPE_OPTIONS, + HeaderValue::from_static("nosniff"), + )) + .layer(SetResponseHeaderLayer::if_not_present( + axum::http::header::STRICT_TRANSPORT_SECURITY, + HeaderValue::from_static("max-age=31536000; includeSubDomains"), + )) + .layer(SetResponseHeaderLayer::if_not_present( + axum::http::header::REFERRER_POLICY, + HeaderValue::from_static("strict-origin-when-cross-origin"), + )) + .layer(SetResponseHeaderLayer::if_not_present( + axum::http::header::CONTENT_SECURITY_POLICY, + HeaderValue::from_static("default-src 'self'"), + )) .with_state(services); let port: u16 = std::env::var("PORT")