Skip to content

Commit f3f5aab

Browse files
author
Lars Schröder
committed
initial commit
0 parents  commit f3f5aab

File tree

8 files changed

+340
-0
lines changed

8 files changed

+340
-0
lines changed

KielCodingSecurityHeaders.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace KielCodingSecurityHeaders;
4+
5+
use Shopware\Components\Plugin;
6+
use Shopware\Components\Plugin\Context\ActivateContext;
7+
use Shopware\Components\Plugin\Context\DeactivateContext;
8+
use Symfony\Component\DependencyInjection\ContainerBuilder;
9+
10+
class KielCodingSecurityHeaders extends Plugin
11+
{
12+
/**
13+
* @param ActivateContext $context
14+
*/
15+
public function activate(ActivateContext $context)
16+
{
17+
$context->scheduleClearCache(ActivateContext::CACHE_LIST_FRONTEND);
18+
}
19+
20+
/**
21+
* @param DeactivateContext $context
22+
*/
23+
public function deactivate(DeactivateContext $context)
24+
{
25+
$context->scheduleClearCache(DeactivateContext::CACHE_LIST_FRONTEND);
26+
}
27+
28+
/**
29+
* @param ContainerBuilder $container
30+
*/
31+
public function build(ContainerBuilder $container)
32+
{
33+
$container->setParameter($this->getContainerPrefix() . '.plugin_dir', $this->getPath());
34+
$container->setParameter($this->getContainerPrefix() . '.plugin_name', $this->getName());
35+
36+
parent::build($container);
37+
}
38+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) Lars Schröder
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Security Headers
2+
3+
## Description
4+
Add security headers to Shopware installations.
5+
Required Minimum Shopware Version: 5.2
6+
7+
## Installation
8+
9+
### Release Version
10+
11+
* Download the [latest plugin version](https://github.com/kielcoding/KielCodingSecurityHeaders/releases/latest/) (e.g. `KielCodingSecurityHeaders-1.0.0.zip`).
12+
* Upload and install the plugin using Shopware Plugin Manager.
13+
14+
### Git Version
15+
* Checkout Plugin in `/custom/plugins/KielCodingSecurityHeaders`.
16+
* Install the plugin using the Shopware Plugin Manager.
17+
18+
## Usage
19+
* Activate the plugin and enable the security headers you want to be added to your shop.
20+
* Modify the default values of the security headers if needed.
21+
* Add additional custom headers you want to add to your shop.
22+
* You can verify the security headers with online security checks, e.g. [securityheaders.io](https://securityheaders.io/).
23+
24+
## Licence
25+

Resources/config.xml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="../../../../engine/Shopware/Components/Plugin/schema/config.xsd">
4+
<elements>
5+
6+
<element type="boolean">
7+
<name>strictTransportSecurityEnabled</name>
8+
<label>Enable Strict-Transport-Security</label>
9+
<label lang="de">Strict-Transport-Security aktivieren</label>
10+
<value>true</value>
11+
</element>
12+
<element type="boolean">
13+
<name>xFrameOptionsEnabled</name>
14+
<label>Enable X-Frame-Options</label>
15+
<label lang="de">X-Frame-Options aktivieren</label>
16+
<value>true</value>
17+
</element>
18+
<element type="boolean">
19+
<name>xXssProtectionEnabled</name>
20+
<label>Enable X-XSS-Protection</label>
21+
<label lang="de">X-XSS-Protection aktivieren</label>
22+
<value>true</value>
23+
</element>
24+
<element type="boolean">
25+
<name>xContentTypeOptionsEnabled</name>
26+
<label>Enable X-Content-Type-Options</label>
27+
<label lang="de">X-Content-Type-Options aktivieren</label>
28+
<value>true</value>
29+
</element>
30+
<element type="boolean">
31+
<name>referrerPolicyEnabled</name>
32+
<label>Enable Referrer-Policy</label>
33+
<label lang="de">Referrer-Policy aktivieren</label>
34+
<value>true</value>
35+
</element>
36+
<element type="boolean">
37+
<name>contentSecurityPolicyEnabled</name>
38+
<label>Enable Content-Security-Policy</label>
39+
<label lang="de">Content-Security-Policy aktivieren</label>
40+
<value>true</value>
41+
</element>
42+
<element type="boolean">
43+
<name>xPoweredByDisabled</name>
44+
<label>Disable X-Powered-By</label>
45+
<label lang="de">X-Powered-By deaktivieren</label>
46+
<value>true</value>
47+
</element>
48+
49+
<element>
50+
<name>strictTransportSecurity</name>
51+
<label>Strict-Transport-Security</label>
52+
<value>max-age=31536000; includeSubDomains</value>
53+
</element>
54+
<element>
55+
<name>xFrameOptions</name>
56+
<label>X-Frame-Options</label>
57+
<value>SAMEORIGIN</value>
58+
</element>
59+
<element>
60+
<name>xXssProtection</name>
61+
<label>X-XSS-Protection</label>
62+
<value>1; mode=block</value>
63+
</element>
64+
<element>
65+
<name>xContentTypeOptions</name>
66+
<label>X-Content-Type-Options</label>
67+
<value>nosniff</value>
68+
</element>
69+
<element>
70+
<name>referrerPolicy</name>
71+
<label>Referrer-Policy</label>
72+
<value>no-referrer</value>
73+
</element>
74+
<element>
75+
<name>contentSecurityPolicy</name>
76+
<label>Content-Security-Policy</label>
77+
<value>default-src https:; script-src https: 'unsafe-inline' 'unsafe-eval' data:; style-src https: 'unsafe-inline'; font-src https: data:</value>
78+
</element>
79+
<element type="textarea">
80+
<name>customHeaders</name>
81+
<label>Custom Headers</label>
82+
<label lang="de">Eigene Headers</label>
83+
<description>E.g. X-Powered-By: My Company Name</description>
84+
<description lang="de">Z.B. X-Powered-By: Mein Firmenname</description>
85+
</element>
86+
</elements>
87+
</config>

Resources/services.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<container xmlns="http://symfony.com/schema/dic/services"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
5+
<services>
6+
<service id="kiel_coding_trusted_shops_reviews.subscriber.frontend" class="KielCodingSecurityHeaders\Subscriber\Frontend">
7+
<argument type="service" id="service_container" />
8+
<tag name="shopware.event_subscriber" />
9+
</service>
10+
</services>
11+
</container>

Subscriber/Frontend.php

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
namespace KielCodingSecurityHeaders\Subscriber;
4+
5+
use Enlight\Event\SubscriberInterface;
6+
use Shopware\Models\Shop\DetachedShop;
7+
use Symfony\Component\DependencyInjection\ContainerInterface;
8+
9+
class Frontend implements SubscriberInterface
10+
{
11+
/**
12+
* @var ContainerInterface
13+
*/
14+
private $container;
15+
16+
/**
17+
* @var
18+
*/
19+
private $config;
20+
21+
/**
22+
* @param ContainerInterface $container
23+
*/
24+
public function __construct(ContainerInterface $container)
25+
{
26+
$this->container = $container;
27+
$this->config = $this->getPluginConfig();
28+
}
29+
30+
/**
31+
* {@inheritdoc}
32+
*/
33+
public static function getSubscribedEvents()
34+
{
35+
return [
36+
'Enlight_Controller_Action_PostDispatchSecure_Frontend_Index' => 'onPostDispatch',
37+
];
38+
}
39+
40+
/**
41+
* @param \Enlight_Controller_ActionEventArgs $args
42+
*/
43+
public function onPostDispatch(\Enlight_Controller_ActionEventArgs $args)
44+
{
45+
$response = $args->getResponse();
46+
47+
$this->setSecurityHeaders($response);
48+
$this->setCustomHeaders($response);
49+
$this->removeInsecureHeaders($response);
50+
}
51+
52+
/**
53+
* @param \Enlight_Controller_Response_ResponseHttp $response
54+
*/
55+
private function setSecurityHeaders(\Enlight_Controller_Response_ResponseHttp $response)
56+
{
57+
if ($this->config['strictTransportSecurityEnabled']) {
58+
$response->setHeader('Strict-Transport-Security', $this->config['strictTransportSecurity']);
59+
}
60+
if ($this->config['xFrameOptionsEnabled']) {
61+
$response->setHeader('X-Frame-Options', $this->config['xFrameOptions']);
62+
}
63+
if ($this->config['xXssProtectionEnabled']) {
64+
$response->setHeader('X-XSS-Protection', $this->config['xXssProtection']);
65+
}
66+
if ($this->config['xContentTypeOptionsEnabled']) {
67+
$response->setHeader('X-Content-Type-Options', $this->config['xContentTypeOptions']);
68+
}
69+
if ($this->config['referrerPolicyEnabled']) {
70+
$response->setHeader('Referrer-Policy', $this->config['referrerPolicy']);
71+
}
72+
if ($this->config['contentSecurityPolicyEnabled'] && $this->isSecure()) {
73+
if ($this->config['contentSecurityPolicyDebug']) {
74+
$response->setHeader('Content-Security-Policy', $this->config['contentSecurityPolicy']);
75+
} else {
76+
$response->setHeader('Content-Security-Policy-Report-Only', $this->config['contentSecurityPolicy']);
77+
}
78+
}
79+
}
80+
81+
/**
82+
* @param \Enlight_Controller_Response_ResponseHttp $response
83+
*/
84+
private function setCustomHeaders(\Enlight_Controller_Response_ResponseHttp $response)
85+
{
86+
foreach ($this->getCustomHeaders() as $header => $value) {
87+
$response->setHeader($header, $value);
88+
}
89+
}
90+
91+
/**
92+
* @param \Enlight_Controller_Response_ResponseHttp $response
93+
*/
94+
private function removeInsecureHeaders(\Enlight_Controller_Response_ResponseHttp $response)
95+
{
96+
if ($this->config['xPoweredByDisabled']) {
97+
@ini_set('expose_php', 'off');
98+
}
99+
}
100+
101+
/**
102+
* @return array
103+
*/
104+
private function getCustomHeaders()
105+
{
106+
if (empty($this->config['customHeaders'])) {
107+
return [];
108+
}
109+
110+
$headers = explode('\n', $this->config['customHeaders']);
111+
112+
$headersFormatted = [];
113+
foreach ($headers as $header) {
114+
$headerParts = explode(':', $header);
115+
$headersFormatted[$headerParts[0]] = $headerParts[1];
116+
}
117+
118+
return $headersFormatted;
119+
}
120+
121+
/**
122+
* @return array
123+
*/
124+
private function getPluginConfig()
125+
{
126+
$pluginName = $this->container->getParameter('kiel_coding_security_headers.plugin_name');
127+
128+
return $this->container->get('shopware.plugin.cached_config_reader')->getByPluginName($pluginName);
129+
}
130+
131+
/**
132+
* @return bool
133+
*/
134+
private function isSecure()
135+
{
136+
/** @var DetachedShop $shop */
137+
$shop = $this->container->get('shop');
138+
139+
return $shop->getSecure();
140+
}
141+
}

plugin.png

701 Bytes
Loading

plugin.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<plugin xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="../../../engine/Shopware/Components/Plugin/schema/plugin.xsd">
4+
<label>Security Headers</label>
5+
<version>1.0.0</version>
6+
7+
<author>Kiel Coding</author>
8+
<copyright>(c) by Kiel Coding</copyright>
9+
<link>https://kielcoding.de</link>
10+
<license>proprietary</license>
11+
<compatibility minVersion="5.2.0" />
12+
13+
<changelog version="1.0.0">
14+
<changes>Initial Release</changes>
15+
<changes lang="de">Erste Veröffentlichung</changes>
16+
</changelog>
17+
</plugin>

0 commit comments

Comments
 (0)