From e7c37daf01f9d56f26acfb43d03b7fa4fdee8db3 Mon Sep 17 00:00:00 2001 From: Pablo Zmdl Date: Mon, 16 Sep 2024 14:53:19 +0200 Subject: [PATCH] Send a configurable CSP in every HTML response The CSP gets adapted to remote objects being allowed or not. It can be configured or disabled via the config option `content_security_policy` (and `content_security_policy_add_allow_remote`). --- config/defaults.inc.php | 11 +++++++++++ program/include/rcmail_output_html.php | 17 +++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/config/defaults.inc.php b/config/defaults.inc.php index 35901ab698e..bb61f16cc8b 100644 --- a/config/defaults.inc.php +++ b/config/defaults.inc.php @@ -1563,3 +1563,14 @@ // 0 - Reply-All always // 1 - Reply-List if mailing list is detected $config['reply_all_mode'] = 0; + +// The Content-Security-Policy to use if no remote objects are allowed to +// be loaded. If you use plugins you might need to extend this. +// Only change this if you know what you're doing! You can break the whole +// application with changes to this setting! +// To disable completely set the value to `false`; +$config['content_security_policy'] = "default-src 'self' data: blob:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';"; + +// Additions to the Content-Security-Policy to use if remote objects *are* +// allowed to be loaded. +$config['content_security_policy_add_allow_remote'] = 'img-src *; media-src *; font-src: *; frame-src: *;'; diff --git a/program/include/rcmail_output_html.php b/program/include/rcmail_output_html.php index 75e9fbf0e17..8e3f00de8f4 100644 --- a/program/include/rcmail_output_html.php +++ b/program/include/rcmail_output_html.php @@ -728,6 +728,8 @@ public function page_headers() $this->header('X-Frame-Options: sameorigin', true); } } + + $this->add_csp_header(); } /** @@ -2717,4 +2719,19 @@ protected function get_template_logo($type = null, $match = null) return $template_logo; } + + /** + * Add the Content-Security-Policy to the HTTP response headers (unless it + * is disabled). + */ + protected function add_csp_header(): void { + $csp = $this->app->config->get('content_security_policy'); + if (!in_array($csp, ['', false, 'false'])) { + $csp_header = "Content-Security-Policy: $csp"; + if (isset($this->env['safemode']) && $this->env['safemode'] === true) { + $csp_header .= $this->app->config->get('content_security_policy_add_allow_remote'); + } + $this->header($csp_header); + } + } }