magento2-google-tag-manager icon indicating copy to clipboard operation
magento2-google-tag-manager copied to clipboard

CSP issue with inline scripts on checkout, after applying the 2.4.6-p6 patch

Open redo-interactive opened this issue 2 weeks ago • 3 comments

After applying latest security patch from Adobe Commerce/Magento there is an issue on checkout, with inline script in

view/frontend/templates/js.phtml

There is a need to use $secureRenderer->renderTag to generate script with unique nonce.

Magento version #:

2.4.7-p1, 2.4.6-p6, 2.4.5-p8, 2.4.4-p9

Edition (EE, CE, OS, etc):

EE, CE, OS

Expected behavior:

js scripts won't break execution on checkout.

Actual behavior:

js scripts are breaking execution on checkout.

Steps to reproduce:

add product to the cart and go to checkout

Preconditions

M2/AC 2.4.6-p6, PHP 8.1

I have created a fix for this:

<?php
/**
 * Copyright © MagePal LLC. All rights reserved.
 * See COPYING.txt for license details.
 * http://www.magepal.com | [email protected]
 */

/** @var $block MagePal\GoogleTagManager\Block\DataLayer **/
$dataLayerName = $escaper->escapeJs($block->getDataLayerName());
$accountId = $escaper->escapeJs($block->getAccountId());
$containerCode = $block->getEmbeddedCode() ? "+'{$block->getEmbeddedCode()}'" : '';

$gtmScript = <<<SCRIPT
    window.{$dataLayerName} = window.{$dataLayerName} || [];
    SCRIPT;

if (!$block->isGdprEnabled() && $block->addJsInHead() && !$block->isAdvancedSettingsEnabled()) {
    $dataLayerJs = $block->getDataLayerJs();
    $gtmScript .= <<<SCRIPT
            {$dataLayerJs}
            (function(w,d,s,l,i){
            w[l]=w[l]||[];
            w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});
            var f=d.getElementsByTagName(s)[0],
                j=d.createElement(s),
                dl=l!='{$dataLayerName}'?'&l='+l:'';
            j.async=true;
            j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl'{$containerCode}';
            f.parentNode.insertBefore(j,f);
        })(window,document,'script','{$dataLayerName}','{$accountId}');
        SCRIPT;
}

if ($block->isAdvancedSettingsEnabled()) {
    $advancedSettingsJsCode = $block->getAdvancedSettingsJsCode();
    $gtmScript .= <<<SCRIPT
            {$dataLayerJs}
            {$advancedSettingsJsCode}
            SCRIPT;
}

// phpcs:ignore
echo /* @noEscape */ $secureRenderer->renderTag('script', [], $gtmScript, false); ?>

<?php if (($block->isGdprEnabled() || !$block->addJsInHead()) && !$block->isAdvancedSettingsEnabled()): ?>
    <script type="text/x-magento-init">
        {
            "*": {
                "magepalGtmDatalayer": {
                    "isCookieRestrictionModeEnabled": <?= /* @noEscape */ $block->isCookieRestrictionModeEnabled() ?>,
                    "currentWebsite": <?= /* @noEscape */ $block->getCurrentWebsiteId() ?>,
                    "cookieName": "<?= /* @noEscape */ $block->getCookieRestrictionName() ?>",
                    "dataLayer": "<?= /* @noEscape */ $block->getDataLayerName() ?>",
                    "accountId": "<?= /* @noEscape */ $block->getAccountId() ?>",
                    "data": <?= /* @noEscape */ $block->getDataLayerJson() ?>,
                    "isGdprEnabled": <?= /* @noEscape */ $block->isGdprEnabled() ?>,
                    "gdprOption": <?= /* @noEscape */ $block->getGdprOption() ?>,
                    "addJsInHeader": <?= /* @noEscape */ $block->addJsInHead() ?>,
                    "containerCode": "<?= /* @noEscape */ $block->getEmbeddedCode() ?>"
                }
            }
        }
    </script>
<?php else : ?>
    <script type="text/x-magento-init">
        {
            "*": {
                "magepalGtmDatalayer": {
                    "dataLayer": "<?= /* @noEscape */ $block->getDataLayerName() ?>"
            }
        }
    }
    </script>
<?php endif; ?>
<!-- End Google Tag Manager by MagePal -->


redo-interactive avatar Jun 19 '24 21:06 redo-interactive