Skip to content

Commit 79c7472

Browse files
committed
OWN-150 Add custom policies to CSP header
1 parent 9fa13cf commit 79c7472

File tree

4 files changed

+140
-8
lines changed

4 files changed

+140
-8
lines changed

Config.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,35 @@
1010

1111
class Config
1212
{
13+
/** @var array https://www.w3.org/TR/CSP3/#iana-registry */
14+
const CSP_DIRECTIVES = [
15+
'base-uri',
16+
'child-src',
17+
'connect-src',
18+
'default-src',
19+
'font-src',
20+
'form-action',
21+
'frame-ancestors',
22+
'frame-src',
23+
'img-src',
24+
'manifest-src',
25+
'media-src',
26+
'object-src',
27+
'plugin-types',
28+
'report-uri',
29+
'report-to',
30+
'sandbox',
31+
'script-src',
32+
'script-src-attr',
33+
'script-src-elem',
34+
'style-src',
35+
'style-src-attr',
36+
'style-src-elem',
37+
'worker-src'
38+
];
39+
1340
/** This module name. */
1441
const MODULE = self::MODULE_VENDOR . '_' . self::MODULE_PACKAGE;
1542
const MODULE_PACKAGE = 'Csp';
1643
const MODULE_VENDOR = 'Flancer32';
17-
1844
}

Model/Collector/Db.php

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,40 @@
55
*/
66

77
namespace Flancer32\Csp\Model\Collector;
8+
use Flancer32\Csp\Model\Collector\Db\A\Query\GetRules as QGetRules;
89

910
/**
1011
* Collect policy rules from DB.
1112
*/
1213
class Db
1314
implements \Magento\Csp\Api\PolicyCollectorInterface
1415
{
16+
/** @var \Flancer32\Csp\Model\Collector\Db\A\Query\GetRules */
17+
private $aQGetRules;
18+
19+
public function __construct(
20+
\Flancer32\Csp\Model\Collector\Db\A\Query\GetRules $aQGetRules
21+
) {
22+
$this->aQGetRules = $aQGetRules;
23+
}
1524

1625
public function collect(array $defaultPolicies = []): array
1726
{
18-
$policy = new \Magento\Csp\Model\Policy\FetchPolicy(
19-
'img-src',
20-
false,
21-
['*.medium.com']
22-
);
23-
$defaultPolicies[] = $policy;
27+
$rules = $this->getRules();
28+
foreach ($rules as $rule) {
29+
$id = $rule[QGetRules::A_TYPE];
30+
$source = $rule[QGetRules::A_SOURCE];
31+
$policy = new \Magento\Csp\Model\Policy\FetchPolicy($id, false, [$source]);
32+
$defaultPolicies[] = $policy;
33+
}
2434
return $defaultPolicies;
2535
}
36+
37+
private function getRules()
38+
{
39+
$query = $this->aQGetRules->build();
40+
$conn = $query->getConnection();
41+
$result = $conn->fetchAll($query);
42+
return $result;
43+
}
2644
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
/**
3+
* Authors: Alex Gusev <[email protected]>
4+
* Since: 2020
5+
*/
6+
7+
namespace Flancer32\Csp\Model\Collector\Db\A\Query;
8+
9+
use Flancer32\Csp\Api\Repo\Data\Rule as ERule;
10+
use Flancer32\Csp\Api\Repo\Data\Type\Policy as EType;
11+
12+
class GetRules
13+
implements \Flancer32\Base\Api\Repo\Query\Select
14+
{
15+
/** Tables aliases for external usage ('camelCase' naming) */
16+
const AS_RULE = 'rule';
17+
const AS_TYPE = 'type';
18+
19+
/** Columns/expressions aliases for external usage ('camelCase' naming) */
20+
const A_AREA = 'area';
21+
const A_SOURCE = 'source';
22+
const A_TYPE = 'type';
23+
24+
/** Entities are used in the query (table names w/o prefix) */
25+
const E_RULE = \Flancer32\Csp\Api\Repo\Dao\Rule::ENTITY_NAME;
26+
const E_TYPE = \Flancer32\Csp\Api\Repo\Dao\Type\Policy::ENTITY_NAME;
27+
28+
29+
/** @var \Magento\Framework\DB\Adapter\AdapterInterface */
30+
private $conn; // default connection
31+
32+
/** @var \Magento\Framework\App\ResourceConnection */
33+
private $resource;
34+
35+
public function __construct(
36+
\Magento\Framework\App\ResourceConnection $resource
37+
) {
38+
$this->resource = $resource;
39+
$this->conn = $resource->getConnection();
40+
}
41+
42+
public function build($source = null)
43+
{
44+
/* this is root query builder (started from SELECT) */
45+
$result = $this->conn->select();
46+
/* define tables aliases for internal usage (in this method) */
47+
$asRule = self::AS_RULE;
48+
$asType = self::AS_TYPE;
49+
50+
/* FROM fl32_csp_rule (FROM - for root builder, JOIN - for $source chained builder) */
51+
$tbl = $this->resource->getTableName(self::E_RULE); // name with prefix
52+
$as = $asRule; // alias for 'current table' (currently processed in this block of code)
53+
$cols = [
54+
self::A_AREA => ERule::ADMIN_AREA,
55+
self::A_SOURCE => ERule::SOURCE
56+
];
57+
$result->from([$as => $tbl], $cols); // standard names for the variables
58+
59+
/* LEFT JOIN fl32_csp_type_policy */
60+
$tbl = $this->resource->getTableName(self::E_TYPE);
61+
$as = $asType;
62+
$cols = [
63+
self::A_TYPE => EType::KEY
64+
];
65+
$cond = "$as." . EType::ID . "=$asRule." . ERule::TYPE_ID;
66+
$result->joinLeft([$as => $tbl], $cond, $cols);
67+
68+
/* WHERE */
69+
$byEnabled = "$asRule." . ERule::ENABLED . "=TRUE";
70+
$result->where($byEnabled);
71+
72+
return $result;
73+
}
74+
}

Setup/Patch/Data/InsertPolicyTypes.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
namespace Flancer32\Csp\Setup\Patch\Data;
8+
use Flancer32\Csp\Config as Cfg;
89

910
/**
1011
* Add policy types to codifier.
@@ -32,14 +33,27 @@ public function __construct(
3233

3334
public function apply()
3435
{
35-
foreach (\Magento\Csp\Model\Policy\FetchPolicy::POLICIES as $one) {
36+
$directives = $this->getDirectives();
37+
foreach ($directives as $one) {
3638
$data = new \Flancer32\Csp\Api\Repo\Data\Type\Policy();
3739
$key = trim(strtolower($one));
3840
$data->setKey($key);
3941
$this->daoTypePolicy->create($data);
4042
}
4143
}
4244

45+
/**
46+
* @return array CSP directives to save in 'fl32_csp_type_policy'
47+
*/
48+
private function getDirectives()
49+
{
50+
$mage = \Magento\Csp\Model\Policy\FetchPolicy::POLICIES;
51+
$own = Cfg::CSP_DIRECTIVES;
52+
$merged = array_merge($own, $mage);
53+
$result = array_unique($merged);
54+
return $result;
55+
}
56+
4357
public function getAliases()
4458
{
4559
return [];

0 commit comments

Comments
 (0)