diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Base/ControllerBase.php b/src/opnsense/mvc/app/controllers/OPNsense/Base/ControllerBase.php index dbbbe5f2c..5916af937 100644 --- a/src/opnsense/mvc/app/controllers/OPNsense/Base/ControllerBase.php +++ b/src/opnsense/mvc/app/controllers/OPNsense/Base/ControllerBase.php @@ -36,6 +36,11 @@ use OPNsense\Core\Config; */ class ControllerBase extends ControllerRoot { + /** + * @var array Content-Security-Policy extensions, when set they will be merged with the defaults + */ + protected $content_security_policy = array(); + /** * convert xml form definition to simple data structure to use in our Volt templates * @@ -207,7 +212,24 @@ class ControllerBase extends ControllerRoot // append ACL object to view $this->view->acl = new \OPNsense\Core\ACL(); - $this->response->setHeader('Content-Security-Policy', "script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline' 'unsafe-eval';"); + + // set security policies + $policies = array( + "default-src" => "'self'", + "img-src" => "'self'", + "script-src" => "'self' 'unsafe-inline' 'unsafe-eval'", + "style-src" => "'self' 'unsafe-inline' 'unsafe-eval'"); + foreach ($this->content_security_policy as $policy_name => $policy_content) { + if (empty($policies[$policy_name])) { + $policies[$policy_name] = ""; + } + $policies[$policy_name] .= " {$policy_content}"; + } + $csp = ""; + foreach ($policies as $policy_name => $policy) { + $csp .= $policy_name . " " . $policy . " ;"; + } + $this->response->setHeader('Content-Security-Policy', $csp); $this->response->setHeader('X-Frame-Options', "SAMEORIGIN"); $this->response->setHeader('X-Content-Type-Options', "nosniff"); $this->response->setHeader('X-XSS-Protection', "1; mode=block");