public function ResponseCspSubscriber::onKernelResponse in Content-Security-Policy 8
Add Content-Security-Policy header to response.
Parameters
\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event: The Response event.
File
- src/
EventSubscriber/ ResponseCspSubscriber.php, line 89
Class
- ResponseCspSubscriber
- Class ResponseSubscriber.
Namespace
Drupal\csp\EventSubscriberCode
public function onKernelResponse(FilterResponseEvent $event) {
if (!$event
->isMasterRequest()) {
return;
}
$cspConfig = $this->configFactory
->get('csp.settings');
$libraryDirectives = $this->libraryPolicyBuilder
->getSources();
$response = $event
->getResponse();
if ($response instanceof CacheableResponseInterface) {
$response
->getCacheableMetadata()
->addCacheTags([
'config:csp.settings',
]);
}
foreach ([
'report-only',
'enforce',
] as $policyType) {
if (!$cspConfig
->get($policyType . '.enable')) {
continue;
}
$policy = new Csp();
$policy
->reportOnly($policyType == 'report-only');
foreach ($cspConfig
->get($policyType . '.directives') ?: [] as $directiveName => $directiveOptions) {
if (is_bool($directiveOptions)) {
$policy
->setDirective($directiveName, TRUE);
continue;
}
// This is a directive with a simple array of values.
if (!isset($directiveOptions['base'])) {
$policy
->setDirective($directiveName, $directiveOptions);
continue;
}
switch ($directiveOptions['base']) {
case 'self':
$policy
->setDirective($directiveName, [
Csp::POLICY_SELF,
]);
break;
case 'none':
$policy
->setDirective($directiveName, [
Csp::POLICY_NONE,
]);
break;
case 'any':
$policy
->setDirective($directiveName, [
Csp::POLICY_ANY,
]);
break;
default:
// Initialize to an empty value so that any alter subscribers can
// tell that this directive was enabled.
$policy
->setDirective($directiveName, []);
}
if (!empty($directiveOptions['flags'])) {
$policy
->appendDirective($directiveName, array_map(function ($value) {
return "'" . $value . "'";
}, $directiveOptions['flags']));
}
if (!empty($directiveOptions['sources'])) {
$policy
->appendDirective($directiveName, $directiveOptions['sources']);
}
if (isset($libraryDirectives[$directiveName])) {
$policy
->appendDirective($directiveName, $libraryDirectives[$directiveName]);
}
}
$reportingPluginId = $cspConfig
->get($policyType . '.reporting.plugin');
if ($reportingPluginId) {
$reportingOptions = $cspConfig
->get($policyType . '.reporting.options') ?: [];
$reportingOptions += [
'type' => $policyType,
];
try {
$this->reportingHandlerPluginManager
->createInstance($reportingPluginId, $reportingOptions)
->alterPolicy($policy);
} catch (PluginException $e) {
watchdog_exception('csp', $e);
}
}
$this->eventDispatcher
->dispatch(CspEvents::POLICY_ALTER, new PolicyAlterEvent($policy, $response));
if ($headerValue = $policy
->getHeaderValue()) {
$response->headers
->set($policy
->getHeaderName(), $headerValue);
}
}
}