[TikiWiki-commits] [Git][tikiwiki/tiki][master] [ENH] Expand HTTP Security Headers with Full CORS and Cross-Origin Policy Support
"SoftStart Code \(@softstartcode\) via TikiWiki-cvs" <[email protected]>
| Newsgroups | gmane.comp.cms.tiki.cvs |
|---|---|
| Message-ID | <68d3f504e0b48_2cdf368958da@gitlab-sidekiq-low-urgency-cpu-bound-v2-69d75bf97c-pjxtt.mail> |
SoftStart Code pushed to branch master at Tiki Wiki CMS Groupware / Tiki
Commits:
a053fbdf by Sandeep D at 2025-09-24T13:31:14+00:00
[ENH] Expand HTTP Security Headers with Full CORS and Cross-Origin Policy Support
---
* [ENH] Expand HTTP Security Headers with Full CORS and Cross-Origin Policy Support
Enhance Tiki's security headers to protect against cross-origin vulnerabilities and improve CORS support.
**New CORS Headers:**
- `Access-Control-Allow-Credentials` - Controls whether credentials can be included in cross-origin requests
- `Access-Control-Allow-Methods` - Specifies allowed HTTP methods for cross-origin requests
- `Access-Control-Allow-Headers` - Specifies allowed headers for cross-origin requests
**New Cross-Origin Policy Headers:**
- `Cross-Origin-Resource-Policy` - Controls which cross-origin requests can access resources
- `Cross-Origin-Embedder-Policy` - Controls loading of cross-origin resources in documents
- `Cross-Origin-Opener-Policy` - Controls interaction with other browsing contexts
**Features:**
- **Admin Panel Integration**: All headers configurable via `tiki-admin.php?page=security` → "General Security" tab
- **Smart Validation**: Prevents CORS wildcard conflicts when credentials are enabled
- **MDN Compliance**: All values follow official MDN specifications with proper validation
- **Safe Defaults**: All headers disabled by default for backward compatibility
- **Comprehensive Documentation**: Each header includes detailed descriptions and MDN help links
**Technical Implementation:**
- Headers automatically injected into all HTTP responses via `SmartyTiki.php`
- Preference system with proper dependencies and conditional UI
- Error handling for invalid CORS configurations
- Integration with existing `Access-Control-Allow-Origin` implementation
See merge request tikiwiki/tiki!8639
- - - - -
3 changed files:
- lib/core/Tiki/Smarty/SmartyTiki.php
- lib/prefs/http.php
- templates/admin/include_security.tpl
Changes:
=====================================
lib/core/Tiki/Smarty/SmartyTiki.php
=====================================
@@ -285,7 +285,36 @@ class SmartyTiki extends Smarty
} 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 {
@@ -315,6 +344,73 @@ class SmartyTiki extends Smarty
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':
+ default:
+ header_remove('Cross-Origin-Embedder-Policy');
+ 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':
+ default:
+ header_remove('Cross-Origin-Opener-Policy');
+ break;
+ }
+ }
if ($content_security_policy == 'y') {
$header_value = $prefs['http_header_content_security_policy_value'];
header('Content-Security-Policy: ' . $header_value);
=====================================
lib/prefs/http.php
=====================================
@@ -50,6 +50,14 @@ function prefs_http_list()
'http_header_frame_options',
],
],
+ 'http_header_access_control_allow_credentials' => [
+ 'name' => tra('HTTP header allow credentials'),
+ 'description' => tra('The Access-Control-Allow-Credentials response header tells browsers whether the server allows cross-origin HTTP requests to include credentials.'),
+ 'type' => 'flag',
+ 'default' => 'n',
+ 'perspective' => false,
+ 'tags' => ['advanced']
+ ],
'http_header_xss_protection' => [
'name' => tra('HTTP header x-xss-protection'),
'description' => tra('The x-xss-protection header is designed to enable the cross-site scripting (XSS) filter built into modern web browsers'),
@@ -73,6 +81,72 @@ function prefs_http_list()
'http_header_xss_protection',
],
],
+ 'http_header_cross_origin_embedder_policy' => [
+ 'name' => tra('HTTP header cross-origin-embedder-policy'),
+ 'description' => tra('Controls the loading of cross-origin resources in a document. Setting this header helps enhance security by ensuring that loaded resources explicitly grant permission to be loaded.'),
+ 'type' => 'flag',
+ 'default' => 'n',
+ 'perspective' => false,
+ 'tags' => ['advanced'],
+ ],
+ 'http_header_cross_origin_embedder_policy_value' => [
+ 'name' => tra('Header value'),
+ 'description' => tra('Specifies the policy for loading cross-origin resources. "Require-CORP" requires cross-origin resources to have CORP headers. "Credentialless" allows loading cross-origin resources without credentials. "Unsafe-none" applies no restrictions.'),
+ 'type' => 'list',
+ 'options' => [
+ 'unsafe-none' => tra('None'),
+ 'require-corp' => tra('Require-CORP'),
+ 'credentialless' => tra('Credentialless'),
+ ],
+ 'default' => '',
+ 'perspective' => false,
+ 'tags' => ['advanced'],
+ ],
+ 'http_header_cross_origin_resource_policy' => [
+ 'name' => tra('HTTP header Cross-Origin-Resource-Policy'),
+ 'description' => tra('Defines which cross-origin requests are allowed to access resources on your site. This header can help prevent other sites from reading or loading your site\'s resources without permission.'),
+ 'type' => 'flag',
+ 'default' => 'n',
+ 'perspective' => false,
+ 'tags' => ['advanced'],
+ ],
+ 'http_header_cross_origin_resource_policy_value' => [
+ 'name' => tra('Header value'),
+ 'description' => tra('Determines which origins are allowed to access resources. "Same-Origin" only allows your own site to access resources. "Same-Site" extends this to your entire site, including subdomains. "Cross-Origin" allows any site to access the resources.'),
+ 'type' => 'list',
+ 'options' => [
+ 'same-origin' => tra('Same-Origin: Only same-origin requests are allowed.'),
+ 'same-site' => tra('Same-Site: Only requests from the same site are allowed.'),
+ 'cross-origin' => tra('Cross-Origin: Allows requests from any origin.'),
+ ],
+ 'default' => '',
+ 'perspective' => false,
+ 'tags' => ['advanced'],
+ 'help' => 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy',
+ ],
+ 'http_header_cross_origin_opener_policy' => [
+ 'name' => tra('HTTP header Cross-Origin-Opener-Policy'),
+ 'description' => tra('Enables or disables the sending of the Cross-Origin-Opener-Policy header in HTTP responses from your site. This header controls how the document may interact with other browsing contexts.'),
+ 'type' => 'flag',
+ 'default' => 'n',
+ 'perspective' => false,
+ 'tags' => ['advanced'],
+ ],
+ 'http_header_cross_origin_opener_policy_value' => [
+ 'name' => tra('Header value'),
+ 'description' => tra('Specifies the policy for cross-origin opener policy header.'),
+ 'type' => 'list',
+ 'options' => [
+ 'same-origin' => tra('Same-Origin: Allows the document to be opened only by pages from the same origin.'),
+ 'same-origin-allow-popups' => tra('Same-Origin-Allow-Popups: Allows the document to be opened by pages from the same origin, and allows those pages to open popups.'),
+ 'same-origin-plus-coep' => tra('Same-Origin-Plus-COEP: Allows the document to be opened only by pages from the same origin, and sets the Cross-Origin-Embedder-Policy header to `require-corp`.'),
+ 'unsafe-none' => tra('None: No specific policy is set.'),
+ ],
+ 'default' => '',
+ 'perspective' => false,
+ 'tags' => ['advanced'],
+ 'help' => 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy',
+ ],
'http_header_content_type_options' => [
'name' => tra('HTTP header x-content-type-options'),
'description' => tra('The x-content-type-options header is a marker used by the server to indicate that the MIME types advertised in the Content-Type headers should not be changed and be followed.'),
@@ -104,6 +178,52 @@ function prefs_http_list()
),
'help' => 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy',
],
+ 'http_header_access_control_allow_methods' => [
+ 'name' => tra('HTTP header access-control-allow-methods'),
+ 'description' => tra('Enables or disables the sending of the Access-Control-Allow-Methods header in HTTP responses from your Tiki site. This header is crucial for Cross-Origin Resource Sharing (CORS) and specifies the HTTP methods that are allowed when accessing resources in response to a preflight request.'),
+ 'type' => 'flag',
+ 'default' => 'n',
+ 'perspective' => false,
+ 'tags' => ['advanced'],
+ ],
+ 'http_header_access_control_allow_methods_value' => [
+ 'name' => tra('Header value'),
+ 'type' => 'text',
+ 'default' => '',
+ 'perspective' => false,
+ 'tags' => ['advanced'],
+ 'dependencies' => [
+ 'http_header_access_control_allow_methods',
+ ],
+ 'description' => tr(
+ 'Specifies the HTTP methods that are allowed for cross-origin requests. This setting takes effect only if the HTTP header access-control-allow-methods is enabled. Separate multiple methods with commas. For example, to allow GET, POST, and PUT methods, set this value to %0',
+ '<code>GET, POST, PUT</code>'
+ ),
+ 'help' => 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods',
+ ],
+ 'http_header_access_control_allow_headers' => [
+ 'name' => tra('HTTP header access-control-allow-headers'),
+ 'description' => tra('Enables or disables the sending of the Access-Control-Allow-Headers header in HTTP responses from your Tiki site. This header is crucial for Cross-Origin Resource Sharing (CORS) and specifies the headers that are allowed when making actual requests (after the preflight has been accepted).'),
+ 'type' => 'flag',
+ 'default' => 'n',
+ 'perspective' => false,
+ 'tags' => ['advanced'],
+ ],
+ 'http_header_access_control_allow_headers_value' => [
+ 'name' => tra('Header value'),
+ 'type' => 'text',
+ 'default' => '',
+ 'perspective' => false,
+ 'tags' => ['advanced'],
+ 'dependencies' => [
+ 'http_header_access_control_allow_headers',
+ ],
+ 'description' => tr(
+ 'Specifies the HTTP headers that can be used when making the actual request. This setting takes effect only if the HTTP header access-control-allow-headers is enabled. Separate multiple header names with commas. For example, to allow headers such as Content-Type, Accept, and X-Requested-With, set this value to %0',
+ '<code>Content-Type, Accept, X-Requested-With</code>'
+ ),
+ 'help' => 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers',
+ ],
'http_header_strict_transport_security' => [
'name' => tra('HTTP header strict-transport-security'),
'description' => tra('The Strict-Transport-Security header (often abbreviated as HSTS) is a security feature that lets a web site tell browsers that it should only be communicated with using HTTPS, instead of using HTTP.'),
=====================================
templates/admin/include_security.tpl
=====================================
@@ -143,6 +143,33 @@
{preference name=http_header_content_type_options}
+ {preference name=http_header_access_control_allow_credentials}
+
+ {preference name=http_header_access_control_allow_methods}
+ <div class="adminoptionboxchild" id="http_header_access_control_allow_methods_childcontainer">
+ {preference name=http_header_access_control_allow_methods_value}
+ </div>
+
+ {preference name=http_header_access_control_allow_headers}
+ <div class="adminoptionboxchild" id="http_header_access_control_allow_headers_childcontainer">
+ {preference name=http_header_access_control_allow_headers_value}
+ </div>
+
+ {preference name=http_header_cross_origin_embedder_policy}
+ <div class="adminoptionboxchild" id="http_header_cross_origin_embedder_policy_childcontainer">
+ {preference name=http_header_cross_origin_embedder_policy_value}
+ </div>
+
+ {preference name=http_header_cross_origin_resource_policy}
+ <div class="adminoptionboxchild" id="http_header_cross_origin_resource_policy_childcontainer">
+ {preference name=http_header_cross_origin_resource_policy_value}
+ </div>
+
+ {preference name=http_header_cross_origin_opener_policy}
+ <div class="adminoptionboxchild" id="http_header_cross_origin_opener_policy_childcontainer">
+ {preference name=http_header_cross_origin_opener_policy_value}
+ </div>
+
{preference name=http_header_content_security_policy}
<div class="adminoptionboxchild" id="http_header_content_security_policy_childcontainer">
{preference name=http_header_content_security_policy_value}
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/a053fbdf11254b9aaaa398e7e11194f06a5369d4
--
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/a053fbdf11254b9aaaa398e7e11194f06a5369d4
You're receiving this email because of your account on gitlab.com.
_______________________________________________
TikiWiki-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tikiwiki-cvs