Skip to content

Commit

Permalink
Fix duplicate policy and reduce number of splits (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
mfickers authored Oct 7, 2024
1 parent 1812806 commit 06c0ac7
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 30 deletions.
68 changes: 39 additions & 29 deletions Plugin/Model/Policy/Renderer/CspHeaderSplitter.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use Laminas\Http\Header\HeaderInterface;
use Laminas\Loader\PluginClassLoader;
use Magento\Csp\Api\Data\PolicyInterface;
use Magento\Csp\Model\Policy\Renderer\SimplePolicyHeaderRenderer;
use Magento\Csp\Model\CspRenderer;
use Magento\Framework\App\Response\HttpInterface as HttpResponse;
use Psr\Log\LoggerInterface;

Expand All @@ -37,26 +37,28 @@ public function __construct(
* @param null $result
*/
public function afterRender(
SimplePolicyHeaderRenderer $subject,
CspRenderer $subject,
$result,
PolicyInterface $policy,
HttpResponse $response
): void {
$headerName = $this->getHeaderName($response);
/** @var HeaderInterface $header */
$header = $response->getHeader($headerName);
$policyValue = $header->getFieldValue();
if (!$header instanceof HeaderInterface) {
return;
}

$headerValue = $header->getFieldValue();
$isHeaderSplittingEnabled = $this->config->isHeaderSplittingEnabled();

$maxHeaderSize = $this->config->getMaxHeaderSize();
$currentHeaderSize = strlen($policyValue);
$currentHeaderSize = strlen($headerValue);

if ($isHeaderSplittingEnabled) {
$this->registerCspHeaderPlugins($response);
$this->splitUpCspHeaders($response, $policyValue);
$this->splitUpCspHeaders($response, $headerName, $headerValue);
} else {
if ($maxHeaderSize >= $currentHeaderSize) {
$response->setHeader($headerName, $policyValue, true);
$response->setHeader($headerName, $headerValue, true);
} else {
$this->logger->error(
sprintf(
Expand Down Expand Up @@ -87,33 +89,41 @@ private function registerCspHeaderPlugins(HttpResponse $response): void
/**
* Make sure that the CSP headers are handled as several headers ("multi-header")
*/
private function splitUpCspHeaders(HttpResponse $response, string $policyValue): void
private function splitUpCspHeaders(HttpResponse $response, string $headerName, string $headerValue): void
{
$headerName = $this->getHeaderName($response);
$maxHeaderSize = $this->config->getMaxHeaderSize();

if (!$headerName) {
return;
}
$headerParts[$i = 0] = '';

$maxHeaderSize = $this->config->getMaxHeaderSize();
$newHeaderSize = strlen($policyValue);
$policyValues = explode(';', $headerValue);
foreach ($policyValues as $policyValue) {
$policyValue = trim($policyValue) . ';';
$newHeaderSize = strlen($headerParts[$i]) + strlen($policyValue);

if ($newHeaderSize <= $maxHeaderSize) {
$this->contentHeaders[] = $policyValue;
} else {
$this->logger->error(
sprintf(
'Unable to set the CSP header. The header size of %d bytes exceeds the '.
'maximum size of %d bytes.',
$newHeaderSize,
$maxHeaderSize
)
);
if ($newHeaderSize <= $maxHeaderSize) {
$headerParts[$i] .= $policyValue;

continue;
}

$headerParts[++$i] = $policyValue;
$headerSize = strlen($policyValue);
if ($headerSize > $maxHeaderSize) {
$this->logger->error(
sprintf(
'Unable to set the CSP header. The header size of %d bytes exceeds the '.
'maximum size of %d bytes.',
$headerSize,
$maxHeaderSize
)
);

return;
}
}

foreach ($this->contentHeaders as $i => $headerPart) {
$isFirstEntry = ($i === 0);
$response->setHeader($headerName, $headerPart.';', $isFirstEntry);
foreach ($headerParts as $i => $headerPart) {
$response->setHeader($headerName, $headerPart.';', $i === 0);
}
}

Expand Down
2 changes: 1 addition & 1 deletion etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Basecom\CspSplitHeader\Api\Data\ConfigInterface" type="Basecom\CspSplitHeader\Model\Config"/>

<type name="Magento\Csp\Model\Policy\Renderer\SimplePolicyHeaderRenderer">
<type name="Magento\Csp\Api\CspRendererInterface">
<plugin name="basecomCspHeaderSplitter"
type="Basecom\CspSplitHeader\Plugin\Model\Policy\Renderer\CspHeaderSplitter"
sortOrder="5"/>
Expand Down

0 comments on commit 06c0ac7

Please sign in to comment.