mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
www/nginx: Rework security header forms and adding CSP frame-ancestors and HSTS preload directives (#2702)
The security header edit dialog contains many fields and a tabbed interface for the dialog itself allows better configuration of the headers.
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
PLUGIN_NAME= nginx
|
PLUGIN_NAME= nginx
|
||||||
PLUGIN_VERSION= 1.25
|
PLUGIN_VERSION= 1.26
|
||||||
PLUGIN_COMMENT= Nginx HTTP server and reverse proxy
|
PLUGIN_COMMENT= Nginx HTTP server and reverse proxy
|
||||||
PLUGIN_DEPENDS= nginx
|
PLUGIN_DEPENDS= nginx
|
||||||
PLUGIN_MAINTAINER= franz.fabian.94@gmail.com
|
PLUGIN_MAINTAINER= franz.fabian.94@gmail.com
|
||||||
|
|||||||
+2
-2
@@ -33,11 +33,11 @@ Most are standard but some endpoints support maps, which are not
|
|||||||
supported by OPNsense core.
|
supported by OPNsense core.
|
||||||
|
|
||||||
You can detect them simply as they are doing more than just a mapping
|
You can detect them simply as they are doing more than just a mapping
|
||||||
to the *base methods.
|
to the \*base methods.
|
||||||
|
|
||||||
Such mappings work in the way that they catch up the request,
|
Such mappings work in the way that they catch up the request,
|
||||||
map the internal data first, and then forward their UUIDs
|
map the internal data first, and then forward their UUIDs
|
||||||
to the *base method.
|
to the \*base method.
|
||||||
|
|
||||||
## The nginx plugin as infrastucture
|
## The nginx plugin as infrastucture
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,13 @@ WWW: https://nginx.org/
|
|||||||
Plugin Changelog
|
Plugin Changelog
|
||||||
================
|
================
|
||||||
|
|
||||||
|
1.26
|
||||||
|
|
||||||
|
* Enhancement of security headers (contributed by Manuel Faux)
|
||||||
|
Add Frame-Ancestors, add "preload", removed deprecated HPKP
|
||||||
|
* Performance enhancements for log display
|
||||||
|
* Fixed display of vts and logs for non-default styles
|
||||||
|
|
||||||
1.25
|
1.25
|
||||||
|
|
||||||
* Reworked logging frontent to support filtering and historic view (contributed by Manuel Faux)
|
* Reworked logging frontent to support filtering and historic view (contributed by Manuel Faux)
|
||||||
|
|||||||
+53
-1
@@ -342,7 +342,59 @@ class SettingsController extends ApiMutableModelControllerBase
|
|||||||
// http security headers
|
// http security headers
|
||||||
public function searchsecurityHeaderAction()
|
public function searchsecurityHeaderAction()
|
||||||
{
|
{
|
||||||
return $this->searchBase('security_header', array('description'));
|
$data = $this->searchBase('security_header',
|
||||||
|
['description', 'referrer', 'xssprotection', 'strict_transport_security_time',
|
||||||
|
'enable_csp', 'csp_report_only', 'csp_default_src_enabled', 'csp_script_src_enabled', 'csp_img_src_enabled',
|
||||||
|
'csp_style_src_enabled', 'csp_media_src_enabled', 'csp_font_src_enabled', 'csp_frame_src_enabled',
|
||||||
|
'csp_frame_ancestors_enabled', 'csp_form_action_enabled']);
|
||||||
|
|
||||||
|
// Create "hsts" column (disabled/time)
|
||||||
|
foreach ($data['rows'] as &$row) {
|
||||||
|
if (intval($row['strict_transport_security_time']) > 0) {
|
||||||
|
$row['hsts'] = sprintf(gettext("%d sec"), intval($row['strict_transport_security_time']));
|
||||||
|
} else {
|
||||||
|
$row['hsts'] = gettext('disabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create "csp" column (enabled/report only/disabled)
|
||||||
|
foreach ($data['rows'] as &$row) {
|
||||||
|
if ($row['enable_csp']) {
|
||||||
|
if ($row['csp_report_only']) {
|
||||||
|
$row['csp'] = gettext('report only');
|
||||||
|
} else {
|
||||||
|
$row['csp'] = gettext('enabled');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$row['csp'] = gettext('disabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create "csp_details" column
|
||||||
|
foreach ($data['rows'] as &$row) {
|
||||||
|
if ($row['enable_csp']) {
|
||||||
|
$enabled = [];
|
||||||
|
if ($row['csp_default_src_enabled']) $enabled[] = gettext("Default Source");
|
||||||
|
if ($row['csp_script_src_enabled']) $enabled[] = gettext("Script Source");
|
||||||
|
if ($row['csp_img_src_enabled']) $enabled[] = gettext("Image Source");
|
||||||
|
if ($row['csp_style_src_enabled']) $enabled[] = gettext("Style Source");
|
||||||
|
if ($row['csp_media_src_enabled']) $enabled[] = gettext("Media Source");
|
||||||
|
if ($row['csp_font_src_enabled']) $enabled[] = gettext("Font Source");
|
||||||
|
if ($row['csp_frame_src_enabled']) $enabled[] = gettext("Frame Source");
|
||||||
|
if ($row['csp_frame_ancestors_enabled']) $enabled[] = gettext("Frame Ancestors");
|
||||||
|
if ($row['csp_form_action_enabled']) $enabled[] = gettext("Form Action");
|
||||||
|
|
||||||
|
if (count($enabled)) {
|
||||||
|
$row['csp_details'] = implode(', ', $enabled);
|
||||||
|
} else {
|
||||||
|
$row['csp_details'] = gettext('none');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$row['csp_details'] = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getsecurityHeaderAction($uuid = null)
|
public function getsecurityHeaderAction($uuid = null)
|
||||||
|
|||||||
+175
-39
@@ -1,4 +1,9 @@
|
|||||||
<form>
|
<form>
|
||||||
|
<tab id="general" description="General">
|
||||||
|
<field>
|
||||||
|
<type>header</type>
|
||||||
|
<label>General</label>
|
||||||
|
</field>
|
||||||
<field>
|
<field>
|
||||||
<id>security_header.description</id>
|
<id>security_header.description</id>
|
||||||
<label>Description</label>
|
<label>Description</label>
|
||||||
@@ -36,61 +41,50 @@
|
|||||||
<label>Don't Sniff Content Type</label>
|
<label>Don't Sniff Content Type</label>
|
||||||
<type>checkbox</type>
|
<type>checkbox</type>
|
||||||
</field>
|
</field>
|
||||||
|
<field>
|
||||||
|
<type>header</type>
|
||||||
|
<label>HTTP Strict Transport Security (HSTS)</label>
|
||||||
|
</field>
|
||||||
<field>
|
<field>
|
||||||
<id>security_header.strict_transport_security_time</id>
|
<id>security_header.strict_transport_security_time</id>
|
||||||
<label>Strict Transport Security: Time</label>
|
<label>Time (Max Age)</label>
|
||||||
<type>text</type>
|
<type>text</type>
|
||||||
<help>A time in seconds in which the transport security (TLS) should be enforced.</help>
|
<help>A time in seconds in which the transport security (TLS) should be enforced.</help>
|
||||||
</field>
|
</field>
|
||||||
<field>
|
<field>
|
||||||
<id>security_header.strict_transport_security_include_subdomains</id>
|
<id>security_header.strict_transport_security_include_subdomains</id>
|
||||||
<label>Strict Transport Security: Include Subdomains</label>
|
<label>Include Subdomains</label>
|
||||||
<type>checkbox</type>
|
<type>checkbox</type>
|
||||||
<help>If checked, also subdomains are affected.</help>
|
<help>If checked, also subdomains are affected.</help>
|
||||||
</field>
|
</field>
|
||||||
<field>
|
<field>
|
||||||
<id>security_header.hpkp_keys</id>
|
<id>security_header.strict_transport_security_preload</id>
|
||||||
<label>HTTP Public Key Pinning: Fingerprints</label>
|
<label>Preload</label>
|
||||||
<type>select_multiple</type>
|
|
||||||
<style>tokenize</style>
|
|
||||||
<allownew>true</allownew>
|
|
||||||
<help><![CDATA[ Enter a comma separated list of public key fingerprints here.
|
|
||||||
You can find some documentetion about this feature in the
|
|
||||||
<a href="https://developer.mozilla.org/de/docs/Web/Security/Public_Key_Pinning">Mozilla Wiki</a>.
|
|
||||||
It is not recommended to use this feature with short lived certificates.]]></help>
|
|
||||||
</field>
|
|
||||||
<field>
|
|
||||||
<id>security_header.hpkp_report_only</id>
|
|
||||||
<label>HTTP Public Key Pinning: Report Only</label>
|
|
||||||
<type>checkbox</type>
|
<type>checkbox</type>
|
||||||
<help>If you only want to test it, you can check this box (policy will be deployed but not enforced).</help>
|
<help><![CDATA[If checked, the preload directive is added. Google maintains <a href="https://hstspreload.org/">an HSTS preload service</a>. By following the guidelines and successfully submitting your domain, browsers will never connect to your domain using an insecure connection. While the service is hosted by Google, all browsers have stated an intent to use (or actually started using) the preload list. However, it is not part of the HSTS specification and should not be treated as official.]]></help>
|
||||||
</field>
|
|
||||||
<field>
|
|
||||||
<id>security_header.hpkp_time</id>
|
|
||||||
<label>HTTP Public Key Pinning: Max Age</label>
|
|
||||||
<type>text</type>
|
|
||||||
</field>
|
|
||||||
<field>
|
|
||||||
<id>security_header.hpkp_include_subdomains</id>
|
|
||||||
<label>HTTP Public Key Pinning: Include Subdomains</label>
|
|
||||||
<type>checkbox</type>
|
|
||||||
<help>If checked, also subdomains are affected.</help>
|
|
||||||
</field>
|
|
||||||
<field>
|
|
||||||
<id>security_header.enable_csp</id>
|
|
||||||
<label>Content Security Policy: Enable</label>
|
|
||||||
<type>checkbox</type>
|
|
||||||
<help>If checked, the CSP is enabled.</help>
|
|
||||||
</field>
|
|
||||||
<field>
|
|
||||||
<id>security_header.csp_report_only</id>
|
|
||||||
<label>Content Security Policy: Report Only</label>
|
|
||||||
<type>checkbox</type>
|
|
||||||
<help>If checked, the CSP is not enforced (learning mode).</help>
|
|
||||||
</field>
|
</field>
|
||||||
|
<field>
|
||||||
|
<type>header</type>
|
||||||
|
<label>Content Security Policy (CSP)</label>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.enable_csp</id>
|
||||||
|
<label>Enable</label>
|
||||||
|
<type>checkbox</type>
|
||||||
|
<help>If checked, the Content Security Policy (CSP) header is enabled. A detailed configuration is still required via the other tabs of this sheet.</help>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_report_only</id>
|
||||||
|
<label>Report Only</label>
|
||||||
|
<type>checkbox</type>
|
||||||
|
<help>If checked, the CSP is not enforced (learning mode).</help>
|
||||||
|
</field>
|
||||||
|
</tab>
|
||||||
|
<tab id="default_source" description="Default Source">
|
||||||
<field>
|
<field>
|
||||||
<type>header</type>
|
<type>header</type>
|
||||||
<label>Content Security Policy: Default Source</label>
|
<label>Content Security Policy: Default Source</label>
|
||||||
|
<hint><![CDATA[The setting <em>Content Security Policy: Enable</em> on the <em>General</em> tab needs to be enabled to activate this header.]]></hint>
|
||||||
</field>
|
</field>
|
||||||
<field>
|
<field>
|
||||||
<id>security_header.csp_default_src_enabled</id>
|
<id>security_header.csp_default_src_enabled</id>
|
||||||
@@ -154,9 +148,12 @@
|
|||||||
<type>checkbox</type>
|
<type>checkbox</type>
|
||||||
<help>If this checkbox is checked, all other settings for this directive are ignored and everything will be forbidden.</help>
|
<help>If this checkbox is checked, all other settings for this directive are ignored and everything will be forbidden.</help>
|
||||||
</field>
|
</field>
|
||||||
|
</tab>
|
||||||
|
<tab id="script-src" description="Script">
|
||||||
<field>
|
<field>
|
||||||
<type>header</type>
|
<type>header</type>
|
||||||
<label>Content Security Policy: Script Source</label>
|
<label>Content Security Policy: Script Source</label>
|
||||||
|
<hint><![CDATA[The setting <em>Content Security Policy: Enable</em> on the <em>General</em> tab needs to be enabled to activate this header.]]></hint>
|
||||||
</field>
|
</field>
|
||||||
<field>
|
<field>
|
||||||
<id>security_header.csp_script_src_enabled</id>
|
<id>security_header.csp_script_src_enabled</id>
|
||||||
@@ -220,9 +217,12 @@
|
|||||||
<type>checkbox</type>
|
<type>checkbox</type>
|
||||||
<help>If this checkbox is checked, all other settings for this directive are ignored and everything will be forbidden.</help>
|
<help>If this checkbox is checked, all other settings for this directive are ignored and everything will be forbidden.</help>
|
||||||
</field>
|
</field>
|
||||||
|
</tab>
|
||||||
|
<tab id="image-src" description="Image">
|
||||||
<field>
|
<field>
|
||||||
<type>header</type>
|
<type>header</type>
|
||||||
<label>Content Security Policy: Image Source</label>
|
<label>Content Security Policy: Image Source</label>
|
||||||
|
<hint><![CDATA[The setting <em>Content Security Policy: Enable</em> on the <em>General</em> tab needs to be enabled to activate this header.]]></hint>
|
||||||
</field>
|
</field>
|
||||||
<field>
|
<field>
|
||||||
<id>security_header.csp_img_src_enabled</id>
|
<id>security_header.csp_img_src_enabled</id>
|
||||||
@@ -286,9 +286,12 @@
|
|||||||
<type>checkbox</type>
|
<type>checkbox</type>
|
||||||
<help>If this checkbox is checked, all other settings for this directive are ignored and everything will be forbidden.</help>
|
<help>If this checkbox is checked, all other settings for this directive are ignored and everything will be forbidden.</help>
|
||||||
</field>
|
</field>
|
||||||
|
</tab>
|
||||||
|
<tab id="styleseet-src" description="Stylesheet">
|
||||||
<field>
|
<field>
|
||||||
<type>header</type>
|
<type>header</type>
|
||||||
<label>Content Security Policy: Stylesheet Source</label>
|
<label>Content Security Policy: Stylesheet Source</label>
|
||||||
|
<hint><![CDATA[The setting <em>Content Security Policy: Enable</em> on the <em>General</em> tab needs to be enabled to activate this header.]]></hint>
|
||||||
</field>
|
</field>
|
||||||
<field>
|
<field>
|
||||||
<id>security_header.csp_style_src_enabled</id>
|
<id>security_header.csp_style_src_enabled</id>
|
||||||
@@ -352,9 +355,12 @@
|
|||||||
<type>checkbox</type>
|
<type>checkbox</type>
|
||||||
<help>If this checkbox is checked, all other settings for this directive are ignored and everything will be forbidden.</help>
|
<help>If this checkbox is checked, all other settings for this directive are ignored and everything will be forbidden.</help>
|
||||||
</field>
|
</field>
|
||||||
|
</tab>
|
||||||
|
<tab id="media-src" description="Media">
|
||||||
<field>
|
<field>
|
||||||
<type>header</type>
|
<type>header</type>
|
||||||
<label>Content Security Policy: Media Source</label>
|
<label>Content Security Policy: Media Source</label>
|
||||||
|
<hint><![CDATA[The setting <em>Content Security Policy: Enable</em> on the <em>General</em> tab needs to be enabled to activate this header.]]></hint>
|
||||||
</field>
|
</field>
|
||||||
<field>
|
<field>
|
||||||
<id>security_header.csp_media_src_enabled</id>
|
<id>security_header.csp_media_src_enabled</id>
|
||||||
@@ -418,9 +424,135 @@
|
|||||||
<type>checkbox</type>
|
<type>checkbox</type>
|
||||||
<help>If this checkbox is checked, all other settings for this directive are ignored and everything will be forbidden.</help>
|
<help>If this checkbox is checked, all other settings for this directive are ignored and everything will be forbidden.</help>
|
||||||
</field>
|
</field>
|
||||||
|
</tab>
|
||||||
|
<tab id="frame" description="Frame">
|
||||||
|
<field>
|
||||||
|
<type>header</type>
|
||||||
|
<label>Content Security Policy: Frame Source</label>
|
||||||
|
<hint><![CDATA[The setting <em>Content Security Policy: Enable</em> on the <em>General</em> tab needs to be enabled to activate this header.]]></hint>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_src_enabled</id>
|
||||||
|
<label>Enable</label>
|
||||||
|
<type>checkbox</type>
|
||||||
|
<help>If checked, this part of the CSP is enabled.</help>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_src_data_urls</id>
|
||||||
|
<label>Enable Data URLs</label>
|
||||||
|
<help>Data URLs are used to embed files into HTML (for example images written directly into the src attribute).</help>
|
||||||
|
<type>checkbox</type>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_src_http_urls</id>
|
||||||
|
<label>Enable HTTP(S) URLs</label>
|
||||||
|
<type>select_multiple</type>
|
||||||
|
<allownew>true</allownew>
|
||||||
|
<style>tokenize</style>
|
||||||
|
<help>Allow loading files over HTTP(S) allows downloading of content over other domains or CDNs.
|
||||||
|
You can use wildcards here like https://*.exmaple.com.</help>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_src_inline</id>
|
||||||
|
<label>Enable Inline Scripting</label>
|
||||||
|
<type>checkbox</type>
|
||||||
|
<help>Checking this directive allows to use scripts or styles directly embedded in in the HTML content.
|
||||||
|
Examples are the script and the style tags.</help>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_src_eval</id>
|
||||||
|
<label>Enable Eval</label>
|
||||||
|
<type>checkbox</type>
|
||||||
|
<help>Checking this box allows functions like eval or createFunction in JS, or style attributes for CSS.</help>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_src_self</id>
|
||||||
|
<label>Enable Same Origin (recommended)</label>
|
||||||
|
<type>checkbox</type>
|
||||||
|
<help>Allows everything from the same site (path can differ, but host, protocol and port need to be the same).</help>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_src_blob</id>
|
||||||
|
<label>Enable Blobs</label>
|
||||||
|
<type>checkbox</type>
|
||||||
|
<help>Allows to use blobs as a data source. This usually is content, which is somehow generated in JavaScript.</help>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_src_mediastream</id>
|
||||||
|
<label>Enable Media Streams</label>
|
||||||
|
<type>checkbox</type>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_src_filesystem</id>
|
||||||
|
<label>Enable File System URLs</label>
|
||||||
|
<type>checkbox</type>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_src_none</id>
|
||||||
|
<label>Forbid Explicitly</label>
|
||||||
|
<type>checkbox</type>
|
||||||
|
<help>If this checkbox is checked, all other settings for this directive are ignored and everything will be forbidden.</help>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<type>header</type>
|
||||||
|
<label>Content Security Policy: Frame Ancestors</label>
|
||||||
|
<hint><![CDATA[The setting <em>Content Security Policy: Enable</em> on the <em>General</em> tab needs to be enabled to activate this header.]]></hint>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_ancestors_enabled</id>
|
||||||
|
<label>Enable</label>
|
||||||
|
<type>checkbox</type>
|
||||||
|
<help>If checked, this part of the CSP is enabled.</help>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_ancestors_data_urls</id>
|
||||||
|
<label>Enable Data URLs</label>
|
||||||
|
<help>Data URLs are used to embed files into HTML (for example images written directly into the src attribute).</help>
|
||||||
|
<type>checkbox</type>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_ancestors_http_urls</id>
|
||||||
|
<label>Enable HTTP(S) URLs</label>
|
||||||
|
<type>select_multiple</type>
|
||||||
|
<allownew>true</allownew>
|
||||||
|
<style>tokenize</style>
|
||||||
|
<help>Allow loading files over HTTP(S) allows downloading of content over other domains or CDNs.
|
||||||
|
You can use wildcards here like https://*.exmaple.com.</help>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_ancestors_self</id>
|
||||||
|
<label>Enable Same Origin (recommended)</label>
|
||||||
|
<type>checkbox</type>
|
||||||
|
<help>Allows everything from the same site (path can differ, but host, protocol and port need to be the same).</help>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_ancestors_blob</id>
|
||||||
|
<label>Enable Blobs</label>
|
||||||
|
<type>checkbox</type>
|
||||||
|
<help>Allows to use blobs as a data source. This usually is content, which is somehow generated in JavaScript.</help>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_ancestors_mediastream</id>
|
||||||
|
<label>Enable Media Streams</label>
|
||||||
|
<type>checkbox</type>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_ancestors_filesystem</id>
|
||||||
|
<label>Enable File System URLs</label>
|
||||||
|
<type>checkbox</type>
|
||||||
|
</field>
|
||||||
|
<field>
|
||||||
|
<id>security_header.csp_frame_ancestors_none</id>
|
||||||
|
<label>Forbid Explicitly</label>
|
||||||
|
<type>checkbox</type>
|
||||||
|
<help>If this checkbox is checked, all other settings for this directive are ignored and everything will be forbidden.</help>
|
||||||
|
</field>
|
||||||
|
</tab>
|
||||||
|
<tab id="font-src" description="Font">
|
||||||
<field>
|
<field>
|
||||||
<type>header</type>
|
<type>header</type>
|
||||||
<label>Content Security Policy: Font Source</label>
|
<label>Content Security Policy: Font Source</label>
|
||||||
|
<hint><![CDATA[The setting <em>Content Security Policy: Enable</em> on the <em>General</em> tab needs to be enabled to activate this header.]]></hint>
|
||||||
</field>
|
</field>
|
||||||
<field>
|
<field>
|
||||||
<id>security_header.csp_font_src_enabled</id>
|
<id>security_header.csp_font_src_enabled</id>
|
||||||
@@ -484,9 +616,12 @@
|
|||||||
<type>checkbox</type>
|
<type>checkbox</type>
|
||||||
<help>If this checkbox is checked, all other settings for this directive are ignored and everything will be forbidden.</help>
|
<help>If this checkbox is checked, all other settings for this directive are ignored and everything will be forbidden.</help>
|
||||||
</field>
|
</field>
|
||||||
|
</tab>
|
||||||
|
<tab id="form-action" description="Form">
|
||||||
<field>
|
<field>
|
||||||
<type>header</type>
|
<type>header</type>
|
||||||
<label>Content Security Policy: Form Action</label>
|
<label>Content Security Policy: Form Action</label>
|
||||||
|
<hint><![CDATA[The setting <em>Content Security Policy: Enable</em> on the <em>General</em> tab needs to be enabled to activate this header.]]></hint>
|
||||||
</field>
|
</field>
|
||||||
<field>
|
<field>
|
||||||
<id>security_header.csp_form_action_enabled</id>
|
<id>security_header.csp_form_action_enabled</id>
|
||||||
@@ -550,4 +685,5 @@
|
|||||||
<type>checkbox</type>
|
<type>checkbox</type>
|
||||||
<help>If this checkbox is checked, all other settings for this directive are ignored and everything will be forbidden.</help>
|
<help>If this checkbox is checked, all other settings for this directive are ignored and everything will be forbidden.</help>
|
||||||
</field>
|
</field>
|
||||||
|
</tab>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1194,19 +1194,10 @@
|
|||||||
<Required>Y</Required>
|
<Required>Y</Required>
|
||||||
<default>1</default>
|
<default>1</default>
|
||||||
</strict_transport_security_include_subdomains>
|
</strict_transport_security_include_subdomains>
|
||||||
<hpkp_keys type="CSVListField">
|
<strict_transport_security_preload type="BooleanField">
|
||||||
<Required>N</Required>
|
|
||||||
<mask>/[a-z0-9\+\/=]+(,[a-z0-9\+\/=]+)*/i</mask>
|
|
||||||
</hpkp_keys>
|
|
||||||
<hpkp_report_only type="BooleanField">
|
|
||||||
<Required>Y</Required>
|
<Required>Y</Required>
|
||||||
</hpkp_report_only>
|
<default>0</default>
|
||||||
<hpkp_time type="IntegerField">
|
</strict_transport_security_preload>
|
||||||
<Required>N</Required>
|
|
||||||
</hpkp_time>
|
|
||||||
<hpkp_include_subdomains type="BooleanField">
|
|
||||||
<Required>Y</Required>
|
|
||||||
</hpkp_include_subdomains>
|
|
||||||
<enable_csp type="BooleanField">
|
<enable_csp type="BooleanField">
|
||||||
<Required>Y</Required>
|
<Required>Y</Required>
|
||||||
</enable_csp>
|
</enable_csp>
|
||||||
@@ -1448,6 +1439,76 @@
|
|||||||
<Required>Y</Required>
|
<Required>Y</Required>
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
</csp_font_src_none>
|
</csp_font_src_none>
|
||||||
|
<csp_frame_src_enabled type="BooleanField">
|
||||||
|
<Required>Y</Required>
|
||||||
|
<default>0</default>
|
||||||
|
</csp_frame_src_enabled>
|
||||||
|
<csp_frame_src_data_urls type="BooleanField">
|
||||||
|
<Required>Y</Required>
|
||||||
|
<default>0</default>
|
||||||
|
</csp_frame_src_data_urls>
|
||||||
|
<csp_frame_src_http_urls type="CSVListField">
|
||||||
|
<Required>N</Required>
|
||||||
|
</csp_frame_src_http_urls>
|
||||||
|
<csp_frame_src_inline type="BooleanField">
|
||||||
|
<Required>Y</Required>
|
||||||
|
<default>0</default>
|
||||||
|
</csp_frame_src_inline>
|
||||||
|
<csp_frame_src_eval type="BooleanField">
|
||||||
|
<Required>Y</Required>
|
||||||
|
<default>0</default>
|
||||||
|
</csp_frame_src_eval>
|
||||||
|
<csp_frame_src_self type="BooleanField">
|
||||||
|
<Required>Y</Required>
|
||||||
|
<default>0</default>
|
||||||
|
</csp_frame_src_self>
|
||||||
|
<csp_frame_src_blob type="BooleanField">
|
||||||
|
<Required>Y</Required>
|
||||||
|
<default>0</default>
|
||||||
|
</csp_frame_src_blob>
|
||||||
|
<csp_frame_src_mediastream type="BooleanField">
|
||||||
|
<Required>Y</Required>
|
||||||
|
<default>0</default>
|
||||||
|
</csp_frame_src_mediastream>
|
||||||
|
<csp_frame_src_filesystem type="BooleanField">
|
||||||
|
<Required>Y</Required>
|
||||||
|
<default>0</default>
|
||||||
|
</csp_frame_src_filesystem>
|
||||||
|
<csp_frame_src_none type="BooleanField">
|
||||||
|
<Required>Y</Required>
|
||||||
|
<default>0</default>
|
||||||
|
</csp_frame_src_none>
|
||||||
|
<csp_frame_ancestors_enabled type="BooleanField">
|
||||||
|
<Required>Y</Required>
|
||||||
|
<default>0</default>
|
||||||
|
</csp_frame_ancestors_enabled>
|
||||||
|
<csp_frame_ancestors_data_urls type="BooleanField">
|
||||||
|
<Required>Y</Required>
|
||||||
|
<default>0</default>
|
||||||
|
</csp_frame_ancestors_data_urls>
|
||||||
|
<csp_frame_ancestors_http_urls type="CSVListField">
|
||||||
|
<Required>N</Required>
|
||||||
|
</csp_frame_ancestors_http_urls>
|
||||||
|
<csp_frame_ancestors_self type="BooleanField">
|
||||||
|
<Required>Y</Required>
|
||||||
|
<default>0</default>
|
||||||
|
</csp_frame_ancestors_self>
|
||||||
|
<csp_frame_ancestors_blob type="BooleanField">
|
||||||
|
<Required>Y</Required>
|
||||||
|
<default>0</default>
|
||||||
|
</csp_frame_ancestors_blob>
|
||||||
|
<csp_frame_ancestors_mediastream type="BooleanField">
|
||||||
|
<Required>Y</Required>
|
||||||
|
<default>0</default>
|
||||||
|
</csp_frame_ancestors_mediastream>
|
||||||
|
<csp_frame_ancestors_filesystem type="BooleanField">
|
||||||
|
<Required>Y</Required>
|
||||||
|
<default>0</default>
|
||||||
|
</csp_frame_ancestors_filesystem>
|
||||||
|
<csp_frame_ancestors_none type="BooleanField">
|
||||||
|
<Required>Y</Required>
|
||||||
|
<default>0</default>
|
||||||
|
</csp_frame_ancestors_none>
|
||||||
<csp_form_action_enabled type="BooleanField">
|
<csp_form_action_enabled type="BooleanField">
|
||||||
<Required>Y</Required>
|
<Required>Y</Required>
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
|
|||||||
@@ -478,6 +478,11 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th data-column-id="description" data-type="string" data-sortable="true" data-visible="true">{{ lang._('Description') }}</th>
|
<th data-column-id="description" data-type="string" data-sortable="true" data-visible="true">{{ lang._('Description') }}</th>
|
||||||
|
<th data-column-id="referrer" data-type="string" data-sortable="true" data-visible="false">{{ lang._('Referrer') }}</th>
|
||||||
|
<th data-column-id="xssprotection" data-type="string" data-sortable="true" data-visible="true">{{ lang._('XSS Protection') }}</th>
|
||||||
|
<th data-column-id="hsts" data-type="string" data-sortable="true" data-visible="true">{{ lang._('HSTS') }}</th>
|
||||||
|
<th data-column-id="csp" data-type="string" data-sortable="true" data-visible="true">{{ lang._('CSP') }}</th>
|
||||||
|
<th data-column-id="csp_details" data-type="string" data-sortable="true" data-visible="false">{{ lang._('CSP Rules') }}</th>
|
||||||
<th data-column-id="commands" data-width="7em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
<th data-column-id="commands" data-width="7em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -691,7 +696,7 @@
|
|||||||
{{ partial("layout_partials/base_dialog",['fields': httprewrite,'id':'httprewritedlg', 'label':lang._('Edit URL Rewrite')]) }}
|
{{ partial("layout_partials/base_dialog",['fields': httprewrite,'id':'httprewritedlg', 'label':lang._('Edit URL Rewrite')]) }}
|
||||||
{{ partial("layout_partials/base_dialog",['fields': naxsi_custom_policy,'id':'custompolicydlg', 'label':lang._('Edit WAF Policy')]) }}
|
{{ partial("layout_partials/base_dialog",['fields': naxsi_custom_policy,'id':'custompolicydlg', 'label':lang._('Edit WAF Policy')]) }}
|
||||||
{{ partial("layout_partials/base_dialog",['fields': naxsi_rule,'id':'naxsiruledlg', 'label':lang._('Edit Naxsi Rule')]) }}
|
{{ partial("layout_partials/base_dialog",['fields': naxsi_rule,'id':'naxsiruledlg', 'label':lang._('Edit Naxsi Rule')]) }}
|
||||||
{{ partial("layout_partials/base_dialog",['fields': security_headers,'id':'security_headersdlg', 'label':lang._('Edit Security Headers')]) }}
|
{{ partial("OPNsense/Nginx/tabbed_dialog",['fields': security_headers,'id':'security_headersdlg', 'label':lang._('Edit Security Headers')]) }}
|
||||||
{{ partial("layout_partials/base_dialog",['fields': limit_request_connection,'id':'limit_request_connectiondlg', 'label':lang._('Edit Request Connection Limit')]) }}
|
{{ partial("layout_partials/base_dialog",['fields': limit_request_connection,'id':'limit_request_connectiondlg', 'label':lang._('Edit Request Connection Limit')]) }}
|
||||||
{{ partial("layout_partials/base_dialog",['fields': limit_zone,'id':'limit_zonedlg', 'label':lang._('Edit Limit Zone')]) }}
|
{{ partial("layout_partials/base_dialog",['fields': limit_zone,'id':'limit_zonedlg', 'label':lang._('Edit Limit Zone')]) }}
|
||||||
{{ partial("layout_partials/base_dialog",['fields': cache_path,'id':'cache_pathdlg', 'label':lang._('Edit Cache Path')]) }}
|
{{ partial("layout_partials/base_dialog",['fields': cache_path,'id':'cache_pathdlg', 'label':lang._('Edit Cache Path')]) }}
|
||||||
|
|||||||
@@ -0,0 +1,183 @@
|
|||||||
|
{#
|
||||||
|
# Copyright (c) 2021 Manuel Faux
|
||||||
|
# OPNsense® is Copyright © 2014-2021 by Deciso B.V.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
# are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer.
|
||||||
|
#
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
|
# and/or other materials provided with the distribution.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
# AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||||
|
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#}
|
||||||
|
|
||||||
|
{#
|
||||||
|
# Generate input dialog, uses the following parameters (as associative array):
|
||||||
|
#
|
||||||
|
# fields : list of field type objects, see form_input_tr tag for details
|
||||||
|
# id : form id, used as unique id for this modal form. inner form to place data is called frm_[id]
|
||||||
|
# save button is identified by btn_[id]_save
|
||||||
|
# label : dialog label
|
||||||
|
#}
|
||||||
|
|
||||||
|
{# Volt templates in php7 have issues with scope sometimes, copy input values to make them more unique #}
|
||||||
|
{% set base_dialog_id=id %}
|
||||||
|
{% set base_dialog_fields=fields %}
|
||||||
|
{% set base_dialog_label=label %}
|
||||||
|
|
||||||
|
{# Find if there are help supported or advanced field on this page #}
|
||||||
|
{% set base_dialog_help=false %}
|
||||||
|
{% set base_dialog_advanced=false %}
|
||||||
|
{% for field in base_dialog_fields|default({})%}
|
||||||
|
{% for name,element in field %}
|
||||||
|
{% if name=='help' %}
|
||||||
|
{% set base_dialog_help=true %}
|
||||||
|
{% endif %}
|
||||||
|
{% if name=='advanced' %}
|
||||||
|
{% set base_dialog_advanced=true %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if base_dialog_help|default(false) and base_dialog_advanced|default(false) %}
|
||||||
|
{% break %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
// hook into on-show event to extend validation
|
||||||
|
$('#{{base_dialog_id}}').on('shown.bs.modal', function (e) {
|
||||||
|
$('.nav-tabs a[href="#frm_{{base_dialog_id}}-tab_general"]').tab('show');
|
||||||
|
|
||||||
|
$("#btn_{{base_dialog_id}}_save").click(function() {
|
||||||
|
// TODO: Search for tab with validation errors, but currently only the first tab has even validation rules
|
||||||
|
$('.nav-tabs a[href="#frm_{{base_dialog_id}}-tab_general"]').tab('show');
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
// Read currently selected tab in main form and store for later
|
||||||
|
$('#{{base_dialog_id}}').on('show.bs.modal', function (e) {
|
||||||
|
$('#{{base_dialog_id}}').attr("data-inittab", window.location.hash);
|
||||||
|
});
|
||||||
|
// Restore selected tab of main form as URL was modified by dialog tabs
|
||||||
|
$('#{{base_dialog_id}}').on('hide.bs.modal', function (e) {
|
||||||
|
window.location.hash = $('#{{base_dialog_id}}').attr("data-inittab");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="modal fade" id="{{base_dialog_id}}" tabindex="-1" role="dialog" aria-labelledby="{{base_dialog_id}}Label" aria-hidden="true">
|
||||||
|
<div class="modal-backdrop fade in"></div>
|
||||||
|
<div class="modal-dialog modal-lg">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="{{ lang._('Close') }}"><span aria-hidden="true">×</span></button>
|
||||||
|
<h4 class="modal-title" id="{{base_dialog_id}}Label">{{base_dialog_label}}</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<ul class="nav nav-tabs" role="tablist" id="dialogtabs">
|
||||||
|
{% for field in base_dialog_fields['tabs']|default({})%}
|
||||||
|
<li>
|
||||||
|
<a data-toggle="tab" href="#frm_{{base_dialog_id}}-tab_{{field[0]}}"><b>{{field[1]}}</b></a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
<form id="frm_{{base_dialog_id}}">
|
||||||
|
<div class="content-box tab-content">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped table-condensed">
|
||||||
|
<colgroup>
|
||||||
|
<col class="col-md-3"/>
|
||||||
|
<col class="col-md-{{ 12-3-msgzone_width|default(5) }}"/>
|
||||||
|
<col class="col-md-{{ msgzone_width|default(5) }}"/>
|
||||||
|
</colgroup>
|
||||||
|
<tbody>
|
||||||
|
{% if base_dialog_advanced|default(false) or base_dialog_help|default(false) %}
|
||||||
|
<tr>
|
||||||
|
<td>{% if base_dialog_advanced|default(false) %}<a href="#"><i class="fa fa-toggle-off text-danger" id="show_advanced_formDialog{{base_dialog_id}}"></i></a> <small>{{ lang._('advanced mode') }}</small>{% endif %}</td>
|
||||||
|
<td colspan="2" style="text-align:right;">
|
||||||
|
{% if base_dialog_help|default(false) %}<small>{{ lang._('full help') }}</small> <a href="#"><i class="fa fa-toggle-off text-danger" id="show_all_help_formDialog{{base_dialog_id}}"></i></a>{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% for tab in base_dialog_fields['tabs']|default({})%}
|
||||||
|
<div id="frm_{{base_dialog_id}}-tab_{{tab[0]}}" class="tab-pane fade">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped table-condensed">
|
||||||
|
<colgroup>
|
||||||
|
<col class="col-md-3"/>
|
||||||
|
<col class="col-md-{{ 12-3-msgzone_width|default(5) }}"/>
|
||||||
|
<col class="col-md-{{ msgzone_width|default(5) }}"/>
|
||||||
|
</colgroup>
|
||||||
|
<tbody>
|
||||||
|
{% for field in tab[2]|default({})%}
|
||||||
|
{# looks a bit buggy in the volt templates, field parameters won't reset properly here #}
|
||||||
|
{% set advanced=false %}
|
||||||
|
{% set help=false %}
|
||||||
|
{% set hint=false %}
|
||||||
|
{% set style=false %}
|
||||||
|
{% set maxheight=false %}
|
||||||
|
{% set width=false %}
|
||||||
|
{% set allownew=false %}
|
||||||
|
{% set readonly=false %}
|
||||||
|
{% if field['type'] == 'header' %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="table-responsive {{field['style']|default('')}}">
|
||||||
|
<table class="table table-striped table-condensed">
|
||||||
|
<colgroup>
|
||||||
|
<col class="col-md-3"/>
|
||||||
|
<col class="col-md-{{ 12-3-msgzone_width|default(5) }}"/>
|
||||||
|
<col class="col-md-{{ msgzone_width|default(5) }}"/>
|
||||||
|
</colgroup>
|
||||||
|
<thead>
|
||||||
|
<tr{% if field['advanced']|default(false)=='true' %} data-advanced="true"{% endif %}>
|
||||||
|
<th colspan="3">
|
||||||
|
<h2>{{field['label']}}</h2>
|
||||||
|
{%- if field['hint']|default(false) %}
|
||||||
|
<small>{{field['hint']}}</small>
|
||||||
|
{%- endif %}
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% else %}
|
||||||
|
{{ partial("layout_partials/form_input_tr",field)}}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
{% if hasSaveBtn|default('true') == 'true' %}
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">{{ lang._('Cancel') }}</button>
|
||||||
|
<button type="button" class="btn btn-primary" id="btn_{{base_dialog_id}}_save">{{ lang._('Save') }} <i id="btn_{{base_dialog_id}}_save_progress" class=""></i></button>
|
||||||
|
{% else %}
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">{{ lang._('Close') }}</button>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# security rules
|
||||||
{% if security_rule.referrer is defined %}
|
{% if security_rule.referrer is defined %}
|
||||||
{% do our_headers.append('Referrer-Policy') %}
|
{% do our_headers.append('Referrer-Policy') %}
|
||||||
add_header Referrer-Policy "{{ security_rule.referrer }}" always;
|
add_header Referrer-Policy "{{ security_rule.referrer }}" always;
|
||||||
@@ -13,21 +14,12 @@
|
|||||||
{% if security_rule.strict_transport_security_time is defined %}
|
{% if security_rule.strict_transport_security_time is defined %}
|
||||||
{% do our_headers.append('Strict-Transport-Security') %}
|
{% do our_headers.append('Strict-Transport-Security') %}
|
||||||
add_header Strict-Transport-Security "max-age={{ security_rule.strict_transport_security_time }}{%
|
add_header Strict-Transport-Security "max-age={{ security_rule.strict_transport_security_time }}{%
|
||||||
if security_rule.strict_transport_security_include_subdomains is defined and
|
if security_rule.strict_transport_security_include_subdomains|default('0') == '1' %}; includeSubDomains{% endif %}{%
|
||||||
security_rule.strict_transport_security_include_subdomains == '1' %}; includeSubDomains{% endif %}" always;
|
if security_rule.strict_transport_security_preload|default('0') == '1' %}; preload{% endif %}" always;
|
||||||
{% endif %}
|
|
||||||
{% if security_rule.hpkp_keys is defined and security_rule.hpkp_time is defined %}
|
|
||||||
{% do our_headers.append('Public-Key-Pins') %}
|
|
||||||
{% do our_headers.append('Public-Key-Pins-Report-Only') %}
|
|
||||||
add_header Public-Key-Pins{% if security_rule.hpkp_report_only is defined and security_rule.hpkp_report_only == '1'
|
|
||||||
%}-Report-Only{% endif %} "{% for key in security_rule.hpkp_keys.split(',')
|
|
||||||
%}pin-sha256={{ key }}; {% endfor %}max-age={{ security_rule.hpkp_time }}{%
|
|
||||||
if security_rule.hpkp_include_subdomains is defined and
|
|
||||||
security_rule.hpkp_include_subdomains == '1' %}; includeSubDomains{% endif %}" always;
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if security_rule.enable_csp is defined and security_rule.enable_csp == '1' %}
|
{% if security_rule.enable_csp is defined and security_rule.enable_csp == '1' %}
|
||||||
{% set hash_csp = {} %}
|
{% set hash_csp = {} %}
|
||||||
{% for csp_category in ['default-src', 'script-src', 'img-src', 'style-src', 'media-src', 'font-src', 'form-action'] %}
|
{% for csp_category in ['default-src', 'script-src', 'img-src', 'style-src', 'media-src', 'font-src', 'frame-src', 'frame-ancestors', 'form-action'] %}
|
||||||
{% set prefix = 'csp_' + csp_category.replace('-', '_') + '_' %}
|
{% set prefix = 'csp_' + csp_category.replace('-', '_') + '_' %}
|
||||||
{% if security_rule[prefix + 'enabled'] == '1' %}
|
{% if security_rule[prefix + 'enabled'] == '1' %}
|
||||||
{% set current_list = [] %}
|
{% set current_list = [] %}
|
||||||
|
|||||||
Reference in New Issue
Block a user