From a786cb78351b2f683f71bdedccb6731643070876 Mon Sep 17 00:00:00 2001 From: knylbyte <40831653+knylbyte@users.noreply.github.com> Date: Mon, 18 Aug 2025 17:27:38 +0200 Subject: [PATCH] Use content_security_policy config key --- README.md | 4 ++-- backend/src/api/endpoints/web_index.rs | 2 +- backend/src/model/config/web_ui.rs | 20 +++++++++---------- config/config.yml | 2 +- .../components/config/webui_config_view.rs | 2 +- shared/src/model/config/web_ui.rs | 10 +++------- 6 files changed, 18 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index eb1d8240c..c8358d7f5 100644 --- a/README.md +++ b/README.md @@ -323,7 +323,7 @@ log: ### 1.10 `web_ui` - enabled: default is true, if set to false the web_ui is disabled - user_ui_enabled, true or false, for user bouquet editor -- content-security-policies: configure Content-Security-Policy headers. When `enabled` is true, the default directives `default-src 'self'`, `script-src 'self' nonce-{nonce_b64}`, and `frame-ancestors 'none'` are applied. Additional directives can be added via `custom-attributes`. Enabling CSP may block external images/logos unless allowed via directives like `img-src`. +- content_security_policy: configure Content-Security-Policy headers. When `enabled` is true, the default directives `default-src 'self'`, `script-src 'self' nonce-{nonce_b64}`, and `frame-ancestors 'none'` are applied. Additional directives can be added via `custom-attributes`. Enabling CSP may block external images/logos unless allowed via directives like `img-src`. - path is for web_ui path like `/ui` for reverse proxy integration if necessary. - auth for authentication settings - `enabled` can be deactivated if `enabled` is set to `false`. If not set default is `true`. @@ -335,7 +335,7 @@ log: web_ui: enabled: true user_ui_enabled: true - content-security-policies: + content_security_policy: enabled: true custom-attributes: - "default-src 'self'" diff --git a/backend/src/api/endpoints/web_index.rs b/backend/src/api/endpoints/web_index.rs index 4ebad9bc5..7c64f6dfa 100644 --- a/backend/src/api/endpoints/web_index.rs +++ b/backend/src/api/endpoints/web_index.rs @@ -167,7 +167,7 @@ async fn index( if let Some(csp) = config .web_ui .as_ref() - .and_then(|w| w.content_security_policies.as_ref()) + .and_then(|w| w.content_security_policy.as_ref()) .filter(|c| c.enabled) { let mut attrs = vec![ diff --git a/backend/src/model/config/web_ui.rs b/backend/src/model/config/web_ui.rs index e9abd5188..6fff0ba40 100644 --- a/backend/src/model/config/web_ui.rs +++ b/backend/src/model/config/web_ui.rs @@ -1,9 +1,9 @@ use shared::error::TuliproxError; -use shared::model::{ContentSecurityPoliciesConfigDto, WebUiConfigDto}; +use shared::model::{ContentSecurityPolicyConfigDto, WebUiConfigDto}; use crate::model::{macros, WebAuthConfig}; #[derive(Debug, Clone)] -pub struct ContentSecurityPoliciesConfig { +pub struct ContentSecurityPolicyConfig { pub enabled: bool, pub custom_attributes: Vec, } @@ -12,7 +12,7 @@ pub struct ContentSecurityPoliciesConfig { pub struct WebUiConfig { pub enabled: bool, pub user_ui_enabled: bool, - pub content_security_policies: Option, + pub content_security_policy: Option, pub path: Option, pub auth: Option, pub player_server: Option, @@ -31,14 +31,14 @@ impl WebUiConfig { } } -macros::from_impl!(ContentSecurityPoliciesConfig); -impl From<&ContentSecurityPoliciesConfigDto> for ContentSecurityPoliciesConfig { - fn from(dto: &ContentSecurityPoliciesConfigDto) -> Self { +macros::from_impl!(ContentSecurityPolicyConfig); +impl From<&ContentSecurityPolicyConfigDto> for ContentSecurityPolicyConfig { + fn from(dto: &ContentSecurityPolicyConfigDto) -> Self { Self { enabled: dto.enabled, custom_attributes: dto.custom_attributes.clone() } } } -impl From<&ContentSecurityPoliciesConfig> for ContentSecurityPoliciesConfigDto { - fn from(instance: &ContentSecurityPoliciesConfig) -> Self { +impl From<&ContentSecurityPolicyConfig> for ContentSecurityPolicyConfigDto { + fn from(instance: &ContentSecurityPolicyConfig) -> Self { Self { enabled: instance.enabled, custom_attributes: instance.custom_attributes.clone() } } } @@ -49,7 +49,7 @@ impl From<&WebUiConfigDto> for WebUiConfig { Self { enabled: dto.enabled, user_ui_enabled: dto.user_ui_enabled, - content_security_policies: dto.content_security_policies.as_ref().map(Into::into), + content_security_policy: dto.content_security_policy.as_ref().map(Into::into), path: dto.path.clone(), auth: dto.auth.as_ref().map(Into::into), player_server: dto.player_server.clone(), @@ -61,7 +61,7 @@ impl From<&WebUiConfig> for WebUiConfigDto { Self { enabled: instance.enabled, user_ui_enabled: instance.user_ui_enabled, - content_security_policies: instance.content_security_policies.as_ref().map(Into::into), + content_security_policy: instance.content_security_policy.as_ref().map(Into::into), path: instance.path.clone(), auth: instance.auth.as_ref().map(Into::into), player_server: instance.player_server.clone(), diff --git a/config/config.yml b/config/config.yml index d4b5ef9a7..14a798809 100644 --- a/config/config.yml +++ b/config/config.yml @@ -27,7 +27,7 @@ update_on_boot: false # best not to hammer upstream during testing web_ui: enabled: true user_ui_enabled: true - content-security-policies: + content_security_policy: enabled: true custom-attributes: - "default-src 'self'" diff --git a/frontend/src/app/components/config/webui_config_view.rs b/frontend/src/app/components/config/webui_config_view.rs index a6918eeaf..4e616be0b 100644 --- a/frontend/src/app/components/config/webui_config_view.rs +++ b/frontend/src/app/components/config/webui_config_view.rs @@ -57,7 +57,7 @@ pub fn WebUiConfigView() -> Html { { config_field_bool!(web_ui, translate.t("LABEL.USER_UI_ENABLED"), user_ui_enabled) } { config_field_child!(translate.t("LABEL.CONTENT_SECURITY_POLICY"), { html! { - match web_ui.content_security_policies.as_ref() { + match web_ui.content_security_policy.as_ref() { Some(csp) => html! { <> { config_field_bool!(csp, translate.t("LABEL.ENABLED"), enabled) } diff --git a/shared/src/model/config/web_ui.rs b/shared/src/model/config/web_ui.rs index 351a61a2b..39cd7bba7 100644 --- a/shared/src/model/config/web_ui.rs +++ b/shared/src/model/config/web_ui.rs @@ -23,7 +23,7 @@ const RESERVED_PATHS: &[&str] = &[ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default, PartialEq)] #[serde(deny_unknown_fields, rename_all = "kebab-case")] -pub struct ContentSecurityPoliciesConfigDto { +pub struct ContentSecurityPolicyConfigDto { #[serde(default)] pub enabled: bool, #[serde(default, skip_serializing_if = "Vec::is_empty")] @@ -37,12 +37,8 @@ pub struct WebUiConfigDto { pub enabled: bool, #[serde(default = "default_as_true")] pub user_ui_enabled: bool, - #[serde( - default, - skip_serializing_if = "Option::is_none", - rename = "content-security-policies" - )] - pub content_security_policies: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub content_security_policy: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub path: Option, #[serde(default, skip_serializing_if = "Option::is_none")]