aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGravatar Marien Fressinaud <dev@marienfressinaud.fr> 2019-12-07 19:29:23 +0100
committerGravatar Marien Fressinaud <dev@marienfressinaud.fr> 2019-12-22 15:01:02 +0100
commit7802fd33a627dc7c582df871cfa613d9be8f8788 (patch)
tree475d6a11b3314561cb90c7d9c480e4620f1d8dac /lib
parent2b1f8e67f76672a5b1b0a1b0403d81dbee364c58 (diff)
tec: Allow to change CSP header from controllers
For an extension, I needed to call a script from an external domain. Unfortunately, the CSP headers didn't allow this domain and I had to patch manually the FreshRSS FrontController for my extension. It's obviously not a long-term solution since it has nothing to do in the core of FRSS, and I don't want to apply this patch manually at each update. With this patch, I allow changing the CSP header from inside the controller actions. It allows extensions to modify headers. It's also an opportunity to remove a bit of code from the FrontController. I wasn't happy with the previous implementation anyhow. Reference: https://github.com/flusio/xExtension-Flus/commit/ed12d56#diff-ff12e33ed31b23bda327499fa6e84eccR143
Diffstat (limited to 'lib')
-rw-r--r--lib/Minz/ActionController.php36
-rw-r--r--lib/Minz/Dispatcher.php1
2 files changed, 37 insertions, 0 deletions
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) {