[TikiWiki-commits] [Git][tikiwiki/tiki][27.x] [BP][FIX] Implement centralized security headers management

"Rodriguez Nyiringabo \(@rodriguezny\) via TikiWiki-cvs" <[email protected]>
Newsgroups gmane.comp.cms.tiki.cvs
Message-ID <6a22df1290c38_38194600483d1@gitlab-sidekiq-low-urgency-cpu-bound-v2-679d75d87c-nnt68.mail>

Rodriguez Nyiringabo pushed to branch 27.x at Tiki Wiki CMS Groupware / Tiki


Commits:
b34f1d52 by Rodriguez Nyiringabo at 2026-06-05T14:30:41+00:00
[BP][FIX] Implement centralized security headers management
---
* [BP][FIX] Implement centralized security headers management
---
* [BP][FIX] Implement centralized security headers management
---
* [FIX] Headelib: Rename method  `add_security_headers` to `addSecurityHeaders` for consistency.
---
* [FIX] Headelib: Rename method  addSecurityHeaders` to `add_security_headers` for consistency.

See merge request tikiwiki/tiki!10445

* [FIX] Implement centralized security headers management
---
* [FIX] Implement centralized security headers management

See merge request tikiwiki/tiki!10437

See merge request tikiwiki/tiki!10444

See merge request tikiwiki/tiki!10446

See merge request tikiwiki/tiki!10447

- - - - -


3 changed files:

- lib/headerlib.php
- lib/init/smarty.php
- tiki-login.php


Changes:

=====================================
lib/headerlib.php
=====================================
@@ -220,6 +220,208 @@ class HeaderLib
         $this->title = urlencode($string);
     }
 
+    /**
+     * Add security headers. By default these headers are not sent.
+     * To change go to admin > security > site access
+     */
+    public function addSecurityHeaders()
+    {
+        global $prefs;
+
+        if (! headers_sent()) {
+            if (! isset($prefs['http_header_frame_options'])) {
+                $frame = false;
+            } else {
+                $frame = $prefs['http_header_frame_options'];
+            }
+            if (! isset($prefs['http_header_xss_protection'])) {
+                $xss = false;  // prevent smarty E_NOTICE
+            } else {
+                $xss = $prefs['http_header_xss_protection'];
+            }
+
+            if (! isset($prefs['http_header_content_type_options'])) {
+                $content_type_options = false;  // prevent smarty E_NOTICE
+            } else {
+                $content_type_options = $prefs['http_header_content_type_options'];
+            }
+            if (! isset($prefs['http_header_access_control_allow_credentials'])) {
+                $access_control_allow_credentials = false;
+            } else {
+                $access_control_allow_credentials = $prefs['http_header_access_control_allow_credentials'];
+            }
+            if (! isset($prefs['http_header_access_control_allow_methods'])) {
+                $access_control_allow_methods = false;
+            } else {
+                $access_control_allow_methods = $prefs['http_header_access_control_allow_methods'];
+            }
+            if (! isset($prefs['http_header_access_control_allow_headers'])) {
+                $access_control_allow_headers = false;
+            } else {
+                $access_control_allow_headers = $prefs['http_header_access_control_allow_headers'];
+            }
+            if (! isset($prefs['http_header_cross_origin_embedder_policy'])) {
+                $cross_origin_embedder_policy = false;
+            } else {
+                $cross_origin_embedder_policy = $prefs['http_header_cross_origin_embedder_policy'];
+            }
+            if (! isset($prefs['http_header_cross_origin_resource_policy'])) {
+                $cross_origin_resource_policy = false;
+            } else {
+                $cross_origin_resource_policy = $prefs['http_header_cross_origin_resource_policy'];
+            }
+            if (! isset($prefs['http_header_cross_origin_opener_policy'])) {
+                $cross_origin_opener_policy = false;
+            } else {
+                $cross_origin_opener_policy = $prefs['http_header_cross_origin_opener_policy'];
+            }
+            if (! isset($prefs['http_header_content_security_policy'])) {
+                $content_security_policy = false;  // prevent smarty E_NOTICE
+            } else {
+                $content_security_policy = $prefs['http_header_content_security_policy'];
+            }
+
+            if (! isset($prefs['http_header_strict_transport_security'])) {
+                $strict_transport_security = false;  // prevent smarty E_NOTICE
+            } else {
+                $strict_transport_security = $prefs['http_header_strict_transport_security'];
+            }
+
+            if (! isset($prefs['http_header_public_key_pins'])) {
+                $public_key_pins = false;  // prevent smarty E_NOTICE
+            } else {
+                $public_key_pins = $prefs['http_header_public_key_pins'];
+            }
+
+            if (! isset($prefs['http_header_referrer_policy'])) {
+                $referrer_policy = false;
+            } else {
+                $referrer_policy = $prefs['http_header_referrer_policy'];
+            }
+
+            if (! isset($prefs['http_header_permitted_cross_domain_policies'])) {
+                $permitted_cross_domain_policies = false;
+            } else {
+                $permitted_cross_domain_policies = $prefs['http_header_permitted_cross_domain_policies'];
+            }
+
+            if ($frame == 'y') {
+                    $header_value = $prefs['http_header_frame_options_value'];
+                    header('X-Frame-Options: ' . $header_value);
+            }
+            if ($xss == 'y') {
+                    $header_value = $prefs['http_header_xss_protection_value'];
+                    header('X-XSS-Protection: ' . $header_value);
+            }
+            if ($content_type_options == 'y') {
+                header('X-Content-Type-Options: nosniff');
+            }
+            if ($access_control_allow_credentials === 'y') {
+                header('Access-Control-Allow-Credentials: true');
+            }
+            if ($access_control_allow_methods === 'y') {
+                $header_value = trim($prefs['http_header_access_control_allow_methods_value']);
+                if ($access_control_allow_credentials === 'y' && $header_value === '*') {
+                    Feedback::error(tr("CORS configuration error: Wildcard (*) is not allowed for Access-Control-Allow-Methods when http_header_access_control_allow_credential is enabled"));
+                    header_remove('Access-Control-Allow-Methods');
+                } else {
+                    header('Access-Control-Allow-Methods: ' . $header_value);
+                }
+            }
+            if ($access_control_allow_headers === 'y') {
+                $headers_value = trim($prefs['http_header_access_control_allow_headers_value']);
+                if ($access_control_allow_credentials === 'y' && $headers_value === '*') {
+                    Feedback::error(tr("CORS configuration error: Wildcard (*) is not allowed for Access-Control-Allow-Headers when Access-Control-Allow-Credentials is enabled."));
+                    header_remove('Access-Control-Allow-Headers');
+                } else {
+                    header('Access-Control-Allow-Headers: ' . $headers_value);
+                }
+            }
+            if ($cross_origin_embedder_policy === 'y') {
+                switch (trim($prefs['http_header_cross_origin_embedder_policy_value'])) {
+                    case 'require-corp':
+                        header('Cross-Origin-Embedder-Policy: require-corp');
+                        break;
+                    case 'credentialless':
+                        header('Cross-Origin-Embedder-Policy: credentialless');
+                        break;
+                    case 'unsafe-none':
+                        header('Cross-Origin-Embedder-Policy: unsafe-none');
+                        break;
+                    default:
+                        break;
+                }
+            }
+            if ($cross_origin_resource_policy === 'y') {
+                switch (trim($prefs['http_header_cross_origin_resource_policy_value'])) {
+                    case 'same-origin':
+                        header('Cross-Origin-Resource-Policy: same-origin');
+                        break;
+                    case 'same-site':
+                        header('Cross-Origin-Resource-Policy: same-site');
+                        break;
+                    case 'cross-origin':
+                        header('Cross-Origin-Resource-Policy: cross-origin');
+                        break;
+                    default:
+                        break;
+                }
+            }
+            if ($cross_origin_opener_policy === 'y') {
+                switch (trim($prefs['http_header_cross_origin_opener_policy_value'])) {
+                    case 'same-origin':
+                        header('Cross-Origin-Opener-Policy: same-origin');
+                        break;
+                    case 'same-origin-allow-popups':
+                        header('Cross-Origin-Opener-Policy: same-origin-allow-popups');
+                        break;
+                    case 'same-origin-plus-coep':
+                        header('Cross-Origin-Opener-Policy: same-origin-plus-coep');
+                        break;
+                    case 'unsafe-none':
+                        header('Cross-Origin-Opener-Policy: unsafe-none');
+                        break;
+                    default:
+                        break;
+                }
+            }
+            if ($content_security_policy == 'y') {
+                $header_value = trim($prefs['http_header_content_security_policy_value']);
+                if ($header_value !== '') {
+                    header('Content-Security-Policy: ' . $header_value);
+                }
+            }
+
+            if ($strict_transport_security == 'y') {
+                $header_value = trim($prefs['http_header_strict_transport_security_value']);
+                if ($header_value !== '') {
+                    header('Strict-Transport-Security: ' . $header_value);
+                }
+            }
+
+            if ($public_key_pins == 'y') {
+                $header_value = trim($prefs['http_header_public_key_pins_value']);
+                if ($header_value !== '') {
+                    header('Public-Key-Pins: ' . $header_value);
+                }
+            }
+
+            if ($referrer_policy === 'y') {
+                $header_value = trim($prefs['http_header_referrer_policy_value']);
+                if ($header_value !== '') {
+                    header('Referrer-Policy: ' . $header_value);
+                }
+            }
+
+            if ($permitted_cross_domain_policies === 'y') {
+                $header_value = trim($prefs['http_header_permitted_cross_domain_policies_value']);
+                if ($header_value !== '') {
+                    header('X-Permitted-Cross-Domain-Policies: ' . $header_value);
+                }
+            }
+        }
+    }
+
     /**
      * Add a js url from this tiki instance to top priority load order.
      * These are usually dynamic created js scripts for configuration, module settings etc.


=====================================
lib/init/smarty.php
=====================================
@@ -384,6 +384,7 @@ class Smarty_Tiki extends \Smarty\Smarty
     ): void {
 
         global $prefs;
+        $headerlib = TikiLib::lib('header');
         $this->activateCustomErrorHandler();
 
         if (! empty($prefs['feature_htmlpurifier_output']) and $prefs['feature_htmlpurifier_output'] == 'y') {
@@ -397,173 +398,7 @@ class Smarty_Tiki extends \Smarty\Smarty
             }
         }
 
-        /**
-         * Add security headers. By default there headers are not sent.
-         * To change go to admin > security > site access
-         */
-        if (! headers_sent()) {
-            if (! isset($prefs['http_header_frame_options'])) {
-                $frame = false;
-            } else {
-                $frame = $prefs['http_header_frame_options'];
-            }
-            if (! isset($prefs['http_header_xss_protection'])) {
-                $xss = false;  // prevent smarty E_NOTICE
-            } else {
-                $xss = $prefs['http_header_xss_protection'];
-            }
-
-            if (! isset($prefs['http_header_content_type_options'])) {
-                $content_type_options = false;  // prevent smarty E_NOTICE
-            } else {
-                $content_type_options = $prefs['http_header_content_type_options'];
-            }
-
-            if (! isset($prefs['http_header_content_security_policy'])) {
-                $content_security_policy = false;  // prevent smarty E_NOTICE
-            } else {
-                $content_security_policy = $prefs['http_header_content_security_policy'];
-            }
-
-            if (! isset($prefs['http_header_strict_transport_security'])) {
-                $strict_transport_security = false;  // prevent smarty E_NOTICE
-            } else {
-                $strict_transport_security = $prefs['http_header_strict_transport_security'];
-            }
-
-            if (! isset($prefs['http_header_public_key_pins'])) {
-                $public_key_pins = false;  // prevent smarty E_NOTICE
-            } else {
-                $public_key_pins = $prefs['http_header_public_key_pins'];
-            }
-
-            if (! isset($prefs['http_header_referrer_policy'])) {
-                $referrer_policy = false;
-            } else {
-                $referrer_policy = $prefs['http_header_referrer_policy'];
-            }
-
-            if (! isset($prefs['http_header_permitted_cross_domain_policies'])) {
-                $permitted_cross_domain_policies = false;
-            } else {
-                $permitted_cross_domain_policies = $prefs['http_header_permitted_cross_domain_policies'];
-            }
-
-            if ($frame == 'y') {
-                    $header_value = $prefs['http_header_frame_options_value'];
-                    header('X-Frame-Options: ' . $header_value);
-            }
-            if ($xss == 'y') {
-                    $header_value = $prefs['http_header_xss_protection_value'];
-                    header('X-XSS-Protection: ' . $header_value);
-            }
-            if ($content_type_options == 'y') {
-                header('X-Content-Type-Options: nosniff');
-            }
-            if ($access_control_allow_credentials === 'y') {
-                header('Access-Control-Allow-Credentials: true');
-            }
-            if ($access_control_allow_methods === 'y') {
-                $header_value = trim($prefs['http_header_access_control_allow_methods_value']);
-                if ($access_control_allow_credentials === 'y' && $header_value === '*') {
-                    Feedback::error(tr("CORS configuration error: Wildcard (*) is not allowed for Access-Control-Allow-Methods when http_header_access_control_allow_credential is enabled"));
-                    header_remove('Access-Control-Allow-Methods');
-                } else {
-                    header('Access-Control-Allow-Methods: ' . $header_value);
-                }
-            }
-            if ($access_control_allow_headers === 'y') {
-                $headers_value = trim($prefs['http_header_access_control_allow_headers_value']);
-                if ($access_control_allow_credentials === 'y' && $headers_value === '*') {
-                    Feedback::error(tr("CORS configuration error: Wildcard (*) is not allowed for Access-Control-Allow-Headers when Access-Control-Allow-Credentials is enabled."));
-                    header_remove('Access-Control-Allow-Headers');
-                } else {
-                    header('Access-Control-Allow-Headers: ' . $headers_value);
-                }
-            }
-            if ($cross_origin_embedder_policy === 'y') {
-                switch (trim($prefs['http_header_cross_origin_embedder_policy_value'])) {
-                    case 'require-corp':
-                        header('Cross-Origin-Embedder-Policy: require-corp');
-                        break;
-                    case 'credentialless':
-                        header('Cross-Origin-Embedder-Policy: credentialless');
-                        break;
-                    case 'unsafe-none':
-                        header('Cross-Origin-Embedder-Policy: unsafe-none');
-                        break;
-                    default:
-                        break;
-                }
-            }
-            if ($cross_origin_resource_policy === 'y') {
-                switch (trim($prefs['http_header_cross_origin_resource_policy_value'])) {
-                    case 'same-origin':
-                        header('Cross-Origin-Resource-Policy: same-origin');
-                        break;
-                    case 'same-site':
-                        header('Cross-Origin-Resource-Policy: same-site');
-                        break;
-                    case 'cross-origin':
-                        header('Cross-Origin-Resource-Policy: cross-origin');
-                        break;
-                    default:
-                        break;
-                }
-            }
-            if ($cross_origin_opener_policy === 'y') {
-                switch (trim($prefs['http_header_cross_origin_opener_policy_value'])) {
-                    case 'same-origin':
-                        header('Cross-Origin-Opener-Policy: same-origin');
-                        break;
-                    case 'same-origin-allow-popups':
-                        header('Cross-Origin-Opener-Policy: same-origin-allow-popups');
-                        break;
-                    case 'same-origin-plus-coep':
-                        header('Cross-Origin-Opener-Policy: same-origin-plus-coep');
-                        break;
-                    case 'unsafe-none':
-                        header('Cross-Origin-Opener-Policy: unsafe-none');
-                        break;
-                    default:
-                        break;
-                }
-            }
-            if ($content_security_policy == 'y') {
-                $header_value = trim($prefs['http_header_content_security_policy_value']);
-                if ($header_value !== '') {
-                    header('Content-Security-Policy: ' . $header_value);
-                }
-            }
-
-            if ($strict_transport_security == 'y') {
-                $header_value = trim($prefs['http_header_strict_transport_security_value']);
-                if ($header_value !== '') {
-                    header('Strict-Transport-Security: ' . $header_value);
-                }
-            }
-
-            if ($public_key_pins == 'y') {
-                $header_value = trim($prefs['http_header_public_key_pins_value']);
-                if ($header_value !== '') {
-                    header('Public-Key-Pins: ' . $header_value);
-                }
-            }
-
-            if ($referrer_policy === 'y') {
-                $header_value = trim($prefs['http_header_referrer_policy_value']);
-                if ($header_value !== '') {
-                    header('Referrer-Policy: ' . $header_value);
-                }
-            }
-
-            if ($permitted_cross_domain_policies === 'y') {
-                $header_value = trim($prefs['http_header_permitted_cross_domain_policies_value']);
-                if ($header_value !== '') {
-                    header('X-Permitted-Cross-Domain-Policies: ' . $header_value);
-                }
-            }
-        }
+        $headerlib->addSecurityHeaders();
 
         /**
          * By default, display is used with text/html content in UTF-8 encoding


=====================================
tiki-login.php
=====================================
@@ -27,6 +27,9 @@ if (empty($_POST['user'])) {
 require_once('tiki-setup.php');
 global $prefs;
 
+$headerlib = TikiLib::lib('header');
+$headerlib->addSecurityHeaders();
+
 // Refresh not logged in since 30 days user's accounts list
 $userlib = TikiLib::lib('user');
 $userlib->refresh_locked_users_list();



View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/b34f1d52f2e3adf87ee0beb9570dcc13ee862d36

-- 
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/b34f1d52f2e3adf87ee0beb9570dcc13ee862d36
You're receiving this email because of your account on gitlab.com. Manage all notifications: https://gitlab.com/-/profile/notifications | Help: https://gitlab.com/help

_______________________________________________
TikiWiki-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tikiwiki-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.