diff --git a/Cargo.toml b/Cargo.toml index ec983d8d29..d6405991da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,7 +94,7 @@ tonic = { version = "0.14", features = [ ] } tonic-health = "0.14" totp-lite = { version = "2.0" } -tower-http = { version = "0.6", features = ["fs", "trace"] } +tower-http = { version = "0.6", features = ["fs", "trace", "set-header"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } trait-variant = "0.1" diff --git a/crates/defguard/src/main.rs b/crates/defguard/src/main.rs index 0db4ef13a5..6838547f4c 100644 --- a/crates/defguard/src/main.rs +++ b/crates/defguard/src/main.rs @@ -19,7 +19,8 @@ use defguard_core::{ }, events::{ApiEvent, BidiStreamEvent, GrpcEvent, InternalEvent}, grpc::{ - WorkerState, gateway::client_state::ClientMap, gateway::map::GatewayMap, + WorkerState, + gateway::{client_state::ClientMap, map::GatewayMap}, run_grpc_bidi_stream, run_grpc_server, }, init_dev_env, init_vpn_location, diff --git a/crates/defguard_core/src/headers.rs b/crates/defguard_core/src/headers.rs index 41b594d675..c9b1bd796d 100644 --- a/crates/defguard_core/src/headers.rs +++ b/crates/defguard_core/src/headers.rs @@ -1,5 +1,6 @@ use std::{borrow::Borrow, sync::LazyLock}; +use axum::http::{HeaderName, HeaderValue}; use sqlx::PgPool; use tokio::sync::mpsc::UnboundedSender; use uaparser::{Client, Parser, UserAgentParser}; @@ -11,6 +12,11 @@ use crate::{ templates::TemplateError, }; +pub(crate) const CONTENT_SECURITY_POLICY_HEADER_NAME: HeaderName = + HeaderName::from_static("content-security-policy"); +pub(crate) const CONTENT_SECURITY_POLICY_HEADER_VALUE: HeaderValue = + HeaderValue::from_static("frame-ancestors 'none';"); + pub(crate) static USER_AGENT_PARSER: LazyLock = LazyLock::new(|| { let regexes = include_bytes!("../user_agent_header_regexes.yaml"); UserAgentParser::from_bytes(regexes).expect("Parser creation failed") diff --git a/crates/defguard_core/src/lib.rs b/crates/defguard_core/src/lib.rs index ea5cf1cdaf..01c0ae4c34 100644 --- a/crates/defguard_core/src/lib.rs +++ b/crates/defguard_core/src/lib.rs @@ -69,7 +69,10 @@ use tokio::{ mpsc::{UnboundedReceiver, UnboundedSender}, }, }; -use tower_http::trace::{DefaultOnResponse, TraceLayer}; +use tower_http::{ + set_header::SetResponseHeaderLayer, + trace::{DefaultOnResponse, TraceLayer}, +}; use tracing::Level; use utoipa::{ Modify, OpenApi, @@ -636,7 +639,12 @@ pub fn build_webapp( .layer(Extension(worker_state)), ); - let webapp = webapp.layer(DefguardVersionLayer::new(version)); + let webapp = webapp.layer(DefguardVersionLayer::new(version)).layer( + SetResponseHeaderLayer::if_not_present( + headers::CONTENT_SECURITY_POLICY_HEADER_NAME, + headers::CONTENT_SECURITY_POLICY_HEADER_VALUE, + ), + ); let swagger = SwaggerUi::new("/api-docs").url("/api-docs/openapi.json", openapi::ApiDoc::openapi()); diff --git a/crates/defguard_core/tests/integration/api/api_tokens.rs b/crates/defguard_core/tests/integration/api/api_tokens.rs index e2cde4b146..d707abe0c8 100644 --- a/crates/defguard_core/tests/integration/api/api_tokens.rs +++ b/crates/defguard_core/tests/integration/api/api_tokens.rs @@ -12,9 +12,8 @@ use serde::Deserialize; use serde_json::json; use sqlx::postgres::{PgConnectOptions, PgPoolOptions}; -use crate::api::common::fetch_user_details; - use super::common::{make_client, make_client_with_state, setup_pool}; +use crate::api::common::fetch_user_details; #[sqlx::test] async fn test_normal_user_cannot_access_token_endpoints( diff --git a/crates/defguard_core/tests/integration/grpc/common/mod.rs b/crates/defguard_core/tests/integration/grpc/common/mod.rs index 6e8e7301b8..ebb31cd0e0 100644 --- a/crates/defguard_core/tests/integration/grpc/common/mod.rs +++ b/crates/defguard_core/tests/integration/grpc/common/mod.rs @@ -7,8 +7,8 @@ use defguard_core::{ enterprise::license::{License, set_cached_license}, events::GrpcEvent, grpc::{ - WorkerState, build_grpc_service_router, gateway::client_state::ClientMap, - gateway::map::GatewayMap, + WorkerState, build_grpc_service_router, + gateway::{client_state::ClientMap, map::GatewayMap}, }, mail::Mail, };