diff options
| -rwxr-xr-x | app/Controllers/indexController.php | 14 | ||||
| -rw-r--r-- | app/Controllers/statsController.php | 5 | ||||
| -rw-r--r-- | app/FreshRSS.php | 17 | ||||
| -rw-r--r-- | lib/Minz/ActionController.php | 36 | ||||
| -rw-r--r-- | lib/Minz/Dispatcher.php | 1 |
5 files changed, 56 insertions, 17 deletions
diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index 967029fd1..276d56acd 100755 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -83,6 +83,13 @@ class FreshRSS_index_Controller extends Minz_ActionController { Minz_Error::error(404); } }; + + $this->_csp([ + 'default-src' => "'self'", + 'frame-src' => '*', + 'img-src' => '* data:', + 'media-src' => '*', + ]); } /** @@ -121,6 +128,13 @@ class FreshRSS_index_Controller extends Minz_ActionController { $title = '(' . FreshRSS_Context::$get_unread . ') ' . $title; } Minz_View::prependTitle($title . ' · '); + + $this->_csp([ + 'default-src' => "'self'", + 'frame-src' => '*', + 'img-src' => '* data:', + 'media-src' => '*', + ]); } /** diff --git a/app/Controllers/statsController.php b/app/Controllers/statsController.php index 1d0d9c124..0d7d8f65a 100644 --- a/app/Controllers/statsController.php +++ b/app/Controllers/statsController.php @@ -15,6 +15,11 @@ class FreshRSS_stats_Controller extends Minz_ActionController { Minz_Error::error(403); } + $this->_csp([ + 'default-src' => "'self'", + 'style-src' => "'self' 'unsafe-inline'", + ]); + Minz_View::prependTitle(_t('admin.stats.title') . ' · '); } diff --git a/app/FreshRSS.php b/app/FreshRSS.php index 8d079b268..886e30323 100644 --- a/app/FreshRSS.php +++ b/app/FreshRSS.php @@ -124,23 +124,6 @@ class FreshRSS extends Minz_FrontController { } public static function preLayout() { - switch (Minz_Request::controllerName()) { - case 'index': - $urlToAuthorize = array_filter(array_map(function ($a) { - if (isset($a['method']) && $a['method'] === 'POST') { - return $a['url']; - } - }, FreshRSS_Context::$user_conf->sharing)); - $connectSrc = count($urlToAuthorize) ? sprintf("; connect-src 'self' %s", implode(' ', $urlToAuthorize)) : ''; - header(sprintf("Content-Security-Policy: default-src 'self'; frame-src *; img-src * data:; media-src *%s", $connectSrc)); - break; - case 'stats': - header("Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'"); - break; - default: - header("Content-Security-Policy: default-src 'self'"); - break; - } header("X-Content-Type-Options: nosniff"); FreshRSS_Share::load(join_path(APP_PATH, 'shares.php')); diff --git a/lib/Minz/ActionController.php b/lib/Minz/ActionController.php index 123b9054c..f60b5411d 100644 --- a/lib/Minz/ActionController.php +++ b/lib/Minz/ActionController.php @@ -9,6 +9,9 @@ */ class Minz_ActionController { protected $view; + private $csp_policies = array( + 'default-src' => "'self'", + ); /** * Constructeur @@ -28,6 +31,39 @@ class Minz_ActionController { } /** + * Set CSP policies. + * + * A default-src directive should always be given. + * + * References: + * - https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP + * - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/default-src + * + * @param array $policies An array where keys are directives and values are sources. + */ + protected function _csp($policies) { + if (!isset($policies['default-src'])) { + $action = Minz_Request::controllerName() . '#' . Minz_Request::actionName(); + Minz_Log::warning( + "Default CSP policy is not declared for action {$action}.", + ADMIN_LOG + ); + } + $this->csp_policies = $policies; + } + + /** + * Send HTTP Content-Security-Policy header based on declared policies. + */ + public function declareCspHeader() { + $policies = []; + foreach ($this->csp_policies as $directive => $sources) { + $policies[] = $directive . ' ' . $sources; + } + header('Content-Security-Policy: ' . implode('; ', $policies)); + } + + /** * Méthodes à redéfinir (ou non) par héritage * firstAction est la première méthode exécutée par le Dispatcher * lastAction est la dernière diff --git a/lib/Minz/Dispatcher.php b/lib/Minz/Dispatcher.php index f05b285b5..7a1c3e1d7 100644 --- a/lib/Minz/Dispatcher.php +++ b/lib/Minz/Dispatcher.php @@ -50,6 +50,7 @@ class Minz_Dispatcher { $this->controller->lastAction (); if (!self::$needsReset) { + $this->controller->declareCspHeader(); $this->controller->view ()->build (); } } catch (Minz_Exception $e) { |
