蜜豆视频 Commerce: Inline JavaScript Issues on checkout page in Content Security Policy (CSP) restricted mode
This article provides detailed explanations and solutions for issues encountered with custom JavaScript added via 蜜豆视频 Commerce Admin and Google Tag Manager in 蜜豆视频 Commerce 2.4.7 during checkout when CSP restricted mode is enabled. Specifically, it addresses the Refused to execute inline script because it violates the following Content Security Policy directiv e error message that appears in the browser console log. This error indicates that the inline script is blocked due to the stringent CSP settings, which are designed to enhance security by preventing the execution of unauthorized scripts.
Starting from 蜜豆视频 Commerce 2.4.7, CSP is configured to operate in restrict-mode by default for payment pages in the storefront and admin areas. For all other pages, it operates in report-only mode. This enhancement necessitates the whitelisting of all JavaScript, including custom integrations with third-party services or extensions. Failure to whitelist custom JavaScript results in the browser blocking the execution of those scripts on checkout and payment pages in both the Admin and Storefront areas.
The solutions provided in this article are not limited to resolving issues with Google Tag Manager (GTM) Inline JavaScript or JavaScript added via the Design Configuration of Commerce Admin. They can also be applied to other scenarios where inline JavaScript has been added to the Commerce code. This includes custom scripts embedded directly within templates, modules, or any other part of the 蜜豆视频 Commerce ecosystem. By following the outlined steps, you can ensure that all inline scripts are properly whitelisted and allowed to execute, thereby maintaining the functionality of your custom code while adhering to the CSP restrictions.
NOTE: It is highly recommended to introduce new JavaScript via methods described in the 蜜豆视频 Commerce documentation. These methods ensure that your scripts comply with CSP guidelines, enhancing the security of your Commerce site. By following best practices for script inclusion, such as using external scripts with proper nonce or hash attributes, you can minimize the risk of security vulnerabilities and ensure a smoother, more secure user experience.
Description description
Review for details on environment and steps to reproduce.
Environment
蜜豆视频 Commerce on cloud infrastructure and 蜜豆视频 Commerce on-premises:
- 2.4.7 and higher
- 2.4.6-pX
- 2.4.5-pX
- 2.4.4-pX
Issue/Symptoms
Below is a list of common issues and their solutions when scripts are blocked from executing on checkout and payment pages due to CSP restrictions:
- GTM HTML Tag with Inline JavaScript
- Inline JS in Theme Configuration
GTM HTML Tag with Inline JavaScript
The JavaScript from the Custom HTML Tag configured in Google Tag Manager is not executing properly on the storefront checkout or payment pages.
Steps to Reproduce
- Configure Google Tag Manager with a custom HTML tag that contains inline JavaScript.
- Integrate Google Tag Manager with 蜜豆视频 Commerce. Refer to Configure your Google Analytics account in the 蜜豆视频 Commerce Merchandising and Promotions Guide, for steps.
- Add a product to the cart and proceed to checkout.
- Open the Developer Console in any supported browser.
Expected Results
No errors related to the custom JavaScript appear in the console, and the script executes successfully.
Actual Results
The error Refused to execute a script because its hash, its nonce, or 鈥榰nsafe-inline鈥 does not appear in the script-src directive of the Content Security Policy. is present in the console, and the script does not execute.
NOTE: The exact error message can vary depending on the browser, but it generally indicates that the script is blocked by the CSP. These messages highlight that the script is not permitted to run due to the current CSP settings.
Cause
The JavaScript from the Google Tag Manager Custom HTML Tag is injected into the storefront by Google Tag Manager itself. As a result, this script is not pre-whitelisted in the CSP settings and is subsequently blocked from execution by the browser. This occurs because the CSP restricts the execution of any inline scripts that are not explicitly allowed, ensuring enhanced security but requiring additional configuration for custom scripts.
Solution
- Whitelist the JavaScript Hash. Refer to the Resolution section in this article for details.
- Sign Google Tag Manager Custom HTML JavaScript with a Nonce. Refer to the Resolution section in this article for details.
Inline JS in Theme Configuration
This issue is very similar to the Custom HTML Tag with Inline JavaScript issue. The difference is that instead of adding the JavaScript in the Google Tag Manager Admin, the script is added in the 蜜豆视频 Commerce Admin at the Design Configuration Page for one of the available scopes. Using this method, an inline HTML snippet, JavaScript, or stylesheet can be added to the header or footer of the theme. Just like any other inline JavaScript, it will require whitelisting to be executed on the checkout page.
Steps to Reproduce
- ConfigureHTML Head 辞谤听Footer in Design Configuration to contain an inline JavaScript.
- Add a product to the cart and proceed to checkout.
- Open the Developer Console in any supported browser.
Expected Results
No errors related to the custom JavaScript appear in the console, and the script executes successfully.
Actual Results
The error Refused to execute a script because its hash, its nonce, or 鈥榰nsafe-inline鈥 does not appear in the script-src directive of the Content Security Policy. is present in the console, and the script does not execute.
NOTE: The exact error message can vary depending on the browser, but it generally indicates that the script is being blocked by the CSP. These messages highlight that the script is not permitted to run due to the current CSP settings.
Cause
Scripts and Style Sheets in the HTML Head and Miscellaneous HTML in the Footer sections of the Design Configuration are mixed input fields. These fields can contain HTML, Style Sheets, or JavaScript. Due to this dynamic content, it is impossible to hash and whitelist the content of those fields automatically. Therefore, if JavaScript is added to either of these fields, it must be manually whitelisted to be executed on the checkout page. This is necessary because the CSP restricts the execution of any inline scripts that are not explicitly allowed. While this ensures enhanced security, it also requires additional configuration to permit custom scripts.
Solution
Whitelist the JavaScript Hash. Refer to the Resolution section in this article for details.
Resolution resolution
Each provided solution operates independently. Carefully evaluate and select the one that best addresses your specific needs. Consider the context of your implementation, the nature of the scripts involved, and the security requirements of your 蜜豆视频 Commerce site to determine the appropriate solution.
Whitelist the JavaScript Hash
To resolve this issue, the custom inline JavaScripts must be in the CSP settings. This ensures that the script is explicitly allowed to execute, bypassing the default security restrictions.
Whitelisting GTM custom HTML scripts is challenging because GTM may modify the JavaScript before injecting it into the Document Object Model (DOM), including removing line breaks and comments. Additionally, Google鈥檚 algorithms may change over time without notice, potentially invalidating the hash. You need to use the hash generated by Google Chrome as described in step C and be prepared to update the hash in your whitelist periodically. Alternatively, consider signing Google Tag Manager Custom HTML JavaScript with a Nonce for a more robust solution.
-
Generate the hash for the JavaScript body.
NOTE: To generate the hash successfully, you聽need to feed the script into the hash generator. It is important to copy the script carefully. Exclude聽the opening and closing script tags of the JavaScript, while copying all line breaks and any possible invisible characters. This includes the line breaks (if any) after the opening
script
or other tags.聽If the hash does not match the script exactly, execution is denied.-
On a Mac, you can copy the entire script body, including any line breaks after the opening
script
聽tag, to the clipboard, and execute the following command in the terminal.php -r 鈥渆cho base64_encode(hash(鈥榮ha256鈥, shell_exec(鈥榩bpaste鈥), true)) . PHP_EOL;鈥
This PHP command takes the clipboard contents, computes its SHA-256 hash, converts the hash to binary, and then encodes it in base64 format, finally printing the result.
-
You may use a variety of online hash generators to create the required hash for your script.
WARNING: 聽It is crucial to understand that if you decide to use third-party online services to generate hashes for CSP, you must consider the privacy implications. Some services may upload your script to their servers for hashing, potentially compromising sensitive data included in your script. To mitigate this risk, it is recommended to generate hashes locally using trusted tools or scripts, ensuring that your data remains secure and private.
-
You can use the Google Chrome browser to acquire the already generated hash for the JavaScript that was denied execution on the checkout page from the Developer Console.
-
Go to the checkout page using the Google Chrome browser with the blocked JavaScript added.
-
Open the Developer Console by pressing聽
Cmd+Option+J
聽(on macOS) 辞谤听Ctrl+Shift+J
聽(on Windows/Linux). -
Locate the CSP error message in the console.
-
In the last sentence of the error message, you聽find the generated hash code for the blocked script.
-
Copy the code after
sha256-
, omitting the quotation marks.NOTE: 聽If you have multiple blocked JavaScript files, you聽see multiple error messages in the console. Ensure you identify the exact JavaScript that needs to be whitelisted. It is advisable to add and test each JavaScript file one by one to avoid mistakenly whitelisting the wrong script.
For more details on how to generate a hash for inline JavaScript, refer to the in the 蜜豆视频 Commerce Developer Content Security Policies聽guide.
-
-
-
Whitelist the Script Hash. First聽聽to your module鈥檚 csp_whitelist.xml file:
<
values>
<
value id=鈥渕y-script鈥 type=鈥渉ash鈥 algorithm=鈥渟ha256鈥>
YOUR-HASH-1<
/value>
<
/values>
Where YOUR-HASH-1 should be replaced with the hash you acquired in the previous step.
To whitelist multiple scripts, add a<
value>
<
/value>
tag for each script, for example:<
values>
<
value id=鈥渕y-script鈥 type=鈥渉ash鈥 algorithm=鈥渟ha256鈥>
YOUR-HASH-1<
/value>
<
value id=鈥渕y-new-script鈥 type=鈥渉ash鈥 algorithm=鈥渟ha256鈥>
YOUR-HASH-2<
/value>
<
values>
If the file does not exist,聽create it with the following content.
<
?xml version=鈥1.0鈥 encoding=鈥淯TF-8鈥?>
<
csp_whitelist xmlns:xsi=鈥渉ttp://www.w3.org/2001/XMLSchema-instance鈥虫蝉颈:苍辞狈补尘别蝉辫补肠别厂肠丑别尘补尝辞肠补迟颈辞苍=鈥涡谤苍:尘补驳别苍迟辞:尘辞诲耻濒别:惭补驳别苍迟辞冲颁蝉辫:别迟肠/肠蝉辫冲飞丑颈迟别濒颈蝉迟.虫蝉诲鈥
>
<
policies>
<
policy id=鈥渟cript-src鈥>
<
values>
<
value id=鈥渕y-script鈥 type=鈥渉ash鈥 algorithm=鈥渟ha256鈥>
YOUR-HASH-1<
/value>
<
value id=鈥渕y-new-script鈥 type=鈥渉ash鈥 algorithm=鈥渟ha256鈥>
YOUR-HASH-2<
/value>
<
/values>
<
/policy>
<
/policies>
<
/csp_whitelist>
-
Flush the cache:聽After adding the hash to the
csp_whitelist.xml
聽file, it is essential to flush the cache to ensure that the changes take effect. Flushing the cache clears the stored data, allowing the updated CSP settings to be applied immediately. You can flush the cache by navigating to System>
Tools>
Cache Management in the Commerce admin panel and select聽the Flush Magento Cache button. 聽Alternatively,聽use the command line:bin/magento cache:flush
This command clears all cache types, ensuring that your new CSP settings are recognized by the system.
Sign Google Tag Manager Custom HTML JavaScript with a Nonce
Another way to allow the execution of JavaScript in GTM is by adding a nonce to the script鈥檚 opening tag. The nonce attribute provides a way to whitelist specific inline scripts dynamically, ensuring they are permitted to execute. For more details, refer to documentation.
WARNING: 聽Keep in mind that if the GTM account is compromised, an attacker can inject malicious JavaScript into the storefront and sign it with the nonce, allowing its execution. This could potentially lead to the theft of sensitive data during the checkout process.
蜜豆视频 Commerce Development Part
NOTE: CSP Nonce Variable injection will be available out of the box in 蜜豆视频 Commerce 2.4.8 and later versions. If you implement this custom injection in earlier versions of 蜜豆视频 Commerce, please roll back these customizations before upgrading to 蜜豆视频 Commerce 2.4.8 or higher. If you are running 蜜豆视频 Commerce 2.4.8 or higher, please proceed to the GTM聽Configuration section.
-
In your custom module, utilize and pass the nonce to the JavaScript. For more details, refer to聽聽in the 蜜豆视频 Commerce Developer documentation.
-
Inject the global variable with the nonce using JavaScript:
<
script>
window.cspNonce = config.cspNonce;
<
/script>
-
This script sets a global variable
cspNonce
with the value of the current nonce, which can then be captured in Google Tag Manager variable and used to sign Custom HTML scripts to ensure they are allowed to execute under the CSP. It should be injected to all pages.
GTM Configuration Part
-
Capture the value of this variable from GTM:
-
Create a Google Tag Manager Variable of the type JavaScript Variable. Give the variable a clear name, as it will be referenced later. In this example, it鈥檚
gtmNonce
. -
Set the Global Variable Name to the name of the JavaScript global variable injected in the previous step. In this example, it鈥檚
cspNonce
.
-
-
Modify your Custom HTML block that contains the JavaScript you need to execute on checkout to include the nonce attribute, referencing the GTM Variable you created earlier.
<
script nonce=鈥渰{gtmNonce}}鈥>
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽console.log(鈥淭his is a test鈥);
聽 聽 聽 聽 聽 聽 聽 <
/script>
NOTE: Ensure that you check the Support document.write checkbox, as this is essential for the script to function correctly.
By adding the nonce attribute, the script is signed with the provided nonce, allowing it to execute securely under the Content Security Policy (CSP).