Skip to content
This repository was archived by the owner on Jan 30, 2020. It is now read-only.

Commit 0451c55

Browse files
committed
Adds support for additional directives in Content-Security-Policy header
Additional supported directives are: - block-all-mixed-content - require-sri-for - trusted-types - upgrade-insecure-requests
1 parent 89d2b79 commit 0451c55

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

src/Header/ContentSecurityPolicy.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ class ContentSecurityPolicy implements MultipleHeaderInterface
5353
// Reporting directives
5454
'report-uri',
5555
'report-to',
56+
57+
// Other directives
58+
'block-all-mixed-content',
59+
'require-sri-for',
60+
'trusted-types',
61+
'upgrade-insecure-requests',
5662
];
5763

5864
/**
@@ -91,13 +97,29 @@ public function setDirective($name, array $sources)
9197
(string) $name
9298
));
9399
}
100+
101+
if ($name === 'block-all-mixed-content'
102+
|| $name === 'upgrade-insecure-requests'
103+
) {
104+
if ($sources) {
105+
throw new Exception\InvalidArgumentException(sprintf(
106+
'Received value for %s directive; none expected',
107+
$name
108+
));
109+
}
110+
111+
$this->directives[$name] = '';
112+
return $this;
113+
}
114+
94115
if (empty($sources)) {
95116
if ('report-uri' === $name) {
96117
if (isset($this->directives[$name])) {
97118
unset($this->directives[$name]);
98119
}
99120
return $this;
100121
}
122+
101123
$this->directives[$name] = "'none'";
102124
return $this;
103125
}
@@ -166,7 +188,7 @@ public function getFieldValue()
166188
foreach ($this->directives as $name => $value) {
167189
$directives[] = sprintf('%s %s;', $name, $value);
168190
}
169-
return implode(' ', $directives);
191+
return str_replace(' ;', ';', implode(' ', $directives));
170192
}
171193

172194
/**

test/Header/ContentSecurityPolicyTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,12 @@ public static function validDirectives()
213213
],
214214
['navigate-to', ['example.com'], 'Content-Security-Policy: navigate-to example.com;'],
215215
['sandbox', ['allow-forms'], 'Content-Security-Policy: sandbox allow-forms;'],
216+
217+
// Other directives
218+
['block-all-mixed-content', [], 'Content-Security-Policy: block-all-mixed-content;'],
219+
['require-sri-for', ['script', 'style'], 'Content-Security-Policy: require-sri-for script style;'],
220+
['trusted-types', ['*'], 'Content-Security-Policy: trusted-types *;'],
221+
['upgrade-insecure-requests', [], 'Content-Security-Policy: upgrade-insecure-requests;'],
216222
];
217223
}
218224

@@ -248,4 +254,27 @@ public function testFromString($directive, array $values, $header)
248254
self::assertArrayHasKey($directive, $contentSecurityPolicy->getDirectives());
249255
self::assertSame(implode(' ', $values), $contentSecurityPolicy->getDirectives()[$directive]);
250256
}
257+
258+
/**
259+
* @return string
260+
*/
261+
public function directivesWithoutValue()
262+
{
263+
yield ['block-all-mixed-content'];
264+
yield ['upgrade-insecure-requests'];
265+
}
266+
267+
/**
268+
* @dataProvider directivesWithoutValue
269+
*
270+
* @param string $directive
271+
*/
272+
public function testExceptionWhenProvideValueWithDirectiveWithoutValue($directive)
273+
{
274+
$csp = new ContentSecurityPolicy();
275+
276+
$this->expectException(InvalidArgumentException::class);
277+
$this->expectExceptionMessage($directive);
278+
$csp->setDirective($directive, ['something']);
279+
}
251280
}

0 commit comments

Comments
 (0)