tpay-com / tpay-magento2-basic

Magento2 basic payments module
MIT License
1 stars 9 forks source link

Tpay module (both ^1.0.0 and ^2.0.0) doesn't work with Magento 2.4.6-p6 due to Csp issues #55

Open wmwnuk opened 3 months ago

wmwnuk commented 3 months ago

Due to some recent Csp security fixes, both versions of your module doesn't work.

VM11861:5 Refused to execute inline script because it violates the following Content Security Policy directive: "(...)" Either the 'unsafe-inline' keyword, a hash ('...'), or a nonce ('nonce-...') is required to enable inline execution.

The offending code I believe is:

The fix should be adding nonce attribute to the script as suggested in the console log. Reference from Adobe: https://developer.adobe.com/commerce/php/development/security/content-security-policies/#using-csp-nonce-provider-to-allow-inline-scripts

EDIT: Also, it seems it's jQuery error: https://stackoverflow.com/a/42464060

wmwnuk commented 3 months ago

Here's a diff / patch for ^1.0.0 version.

--- Model/TpayConfigProvider.old.php    2022-12-21 10:28:07.000000000 +0100
+++ Model/TpayConfigProvider.php    2024-06-17 15:43:50.200778304 +0200
@@ -10,6 +10,8 @@
 namespace tpaycom\magento2basic\Model;

 use Magento\Checkout\Model\ConfigProviderInterface;
+use Magento\Csp\Helper\CspNonceProvider;
+use Magento\Framework\Escaper;
 use Magento\Framework\View\Asset\Repository;
 use Magento\Payment\Model\MethodInterface;
 use tpaycom\magento2basic\Api\TpayInterface;
@@ -39,17 +41,33 @@
     protected $paymentMethod;

     /**
+     * @var CspNonceProvider
+     */
+    protected $cspNonceProvider;
+
+    /**
+     * @var Escaper
+     */
+    protected $escaper;
+
+    /**
      * TpayConfigProvider constructor.
      *
      * @param PaymentHelper $paymentHelper
      * @param Repository $assetRepository
+     * @param CspNonceProvider $cspNonceProvider
+     * @param Escaper $escaper
      */
     public function __construct(
         PaymentHelper $paymentHelper,
-        Repository $assetRepository
+        Repository $assetRepository,
+        CspNonceProvider $cspNonceProvider,
+        Escaper $escaper
     ) {
         $this->assetRepository = $assetRepository;
         $this->paymentHelper = $paymentHelper;
+        $this->cspNonceProvider = $cspNonceProvider;
+        $this->escaper = $escaper;
     }

     /**
@@ -119,10 +137,12 @@
     public function createScript($script)
     {
         return "
-            <script type=\"text/javascript\">
+            <script nonce=\"{$this->cspNonceProvider->generateNonce()}\">
                 require(['jquery'], function ($) {
-                    $.getScript('{$this->generateURL($script)}');
-
+                    let script = document.createElement('script');
+                    script.nonce = '{$this->cspNonceProvider->generateNonce()}';
+                    script.textContent = '{$this->escaper->escapeJs($this->assetRepository->createAsset($script)->getContent())}';
+                    document.head.appendChild(script);
                 });
             </script>";
     }