Skip to content

Commit 4d3b051

Browse files
author
Oleksandr Gorkun
committed
MC-19927: Implement hash-whitelisting, dynamic CSP
1 parent 9419d94 commit 4d3b051

File tree

14 files changed

+281
-5
lines changed

14 files changed

+281
-5
lines changed

app/code/Magento/Csp/Model/CompositePolicyCollector.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ private function merge(array $collected): array
5353
if (array_key_exists($policy->getId(), $merged)) {
5454
foreach ($this->mergers as $merger) {
5555
if ($merger->canMerge($merged[$policy->getId()], $policy)) {
56-
$result[$policy->getId()] = $merger->merge($merged[$policy->getId()], $policy);
56+
$merged[$policy->getId()] = $merger->merge($merged[$policy->getId()], $policy);
5757
continue 2;
5858
}
5959
}

app/code/Magento/Csp/Plugin/CspAwareControllerPlugin.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ public function __construct(ControllerCollector $collector)
3434
* Register matched action instance.
3535
*
3636
* @param RouterInterface $router
37-
* @param ActionInterface $matched
38-
* @return ActionInterface
37+
* @param ActionInterface|null $matched
38+
* @return ActionInterface|null
3939
*/
40-
public function afterMatch(RouterInterface $router, ActionInterface $matched): ActionInterface
40+
public function afterMatch(RouterInterface $router, ?ActionInterface $matched): ?ActionInterface
4141
{
42-
if ($matched instanceof CspAwareActionInterface) {
42+
if ($matched && $matched instanceof CspAwareActionInterface) {
4343
$this->collector->setCurrentActionInstance($matched);
4444
}
4545

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\TestModuleCspUtil\Controller\Csp;
9+
10+
use Magento\Csp\Api\CspAwareActionInterface;
11+
use Magento\Csp\Model\Policy\FetchPolicy;
12+
use Magento\Framework\App\Action\Action;
13+
use Magento\Framework\Controller\ResultFactory;
14+
15+
/**
16+
* CSP Aware controller.
17+
*/
18+
class Aware extends Action implements CspAwareActionInterface
19+
{
20+
/**
21+
* @inheritDoc
22+
*/
23+
public function execute()
24+
{
25+
return $this->resultFactory->create(ResultFactory::TYPE_PAGE);
26+
}
27+
28+
/**
29+
* @inheritDoc
30+
*/
31+
public function modifyCsp(array $appliedPolicies): array
32+
{
33+
$policies = [];
34+
foreach ($appliedPolicies as $policy) {
35+
if ($policy instanceof FetchPolicy && in_array('http://controller.magento.com', $policy->getHostSources(), true)) {
36+
$policies[] = new FetchPolicy(
37+
'script-src',
38+
false,
39+
['https://controller.magento.com'],
40+
[],
41+
true,
42+
false,
43+
false,
44+
[],
45+
['H4RRnauTM2X2Xg/z9zkno1crqhsaY3uKKu97uwmnXXE=' => 'sha256']
46+
);
47+
}
48+
}
49+
50+
return $policies;
51+
}
52+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\TestModuleCspUtil\Controller\Csp;
9+
10+
use Magento\Framework\App\Action\Action;
11+
use Magento\Framework\Controller\ResultFactory;
12+
use Magento\Framework\View\Result\PageFactory;
13+
14+
/**
15+
* .phtml templates utilizes CSP helper.
16+
*/
17+
class Helper extends Action
18+
{
19+
/**
20+
* @inheritDoc
21+
*/
22+
public function execute()
23+
{
24+
return $this->resultFactory->create(ResultFactory::TYPE_PAGE);
25+
}
26+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "magento/module-csp-util",
3+
"description": "test csp module",
4+
"config": {
5+
"sort-packages": true
6+
},
7+
"require": {
8+
"php": "~7.1.3||~7.2.0||~7.3.0",
9+
"magento/framework": "*",
10+
"magento/module-integration": "*"
11+
},
12+
"type": "magento2-module",
13+
"extra": {
14+
"map": [
15+
[
16+
"*",
17+
"Magento/TestModuleCspUtil"
18+
]
19+
]
20+
}
21+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<csp_whitelist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Csp/etc/csp_whitelist.xsd">
9+
<policies>
10+
<policy id="script-src">
11+
<values>
12+
<value id="devdocs-base" type="host">https://devdocs.magento.com</value>
13+
</values>
14+
</policy>
15+
</policies>
16+
</csp_whitelist>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
9+
<router id="standard">
10+
<route id="csputil" frontName="csputil">
11+
<module name="Magento_TestModuleCspUtil" />
12+
</route>
13+
</router>
14+
</config>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
9+
<module name="Magento_TestModuleCspUtil" active="true" />
10+
</config>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
use Magento\Framework\Component\ComponentRegistrar;
8+
9+
$registrar = new ComponentRegistrar();
10+
if ($registrar->getPath(ComponentRegistrar::MODULE, 'Magento_TestModuleCspUtil') === null) {
11+
ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_TestModuleCspUtil', __DIR__);
12+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
9+
<body>
10+
<referenceContainer name="content">
11+
<block class="Magento\Framework\View\Element\Template"
12+
name="csp_helper"
13+
cacheable="false"
14+
template="Magento_TestModuleCspUtil::helper.phtml" />
15+
</referenceContainer>
16+
</body>
17+
</page>

0 commit comments

Comments
 (0)