diff --git a/vendor/magento/module-csp/Model/BlockCache.php b/vendor/magento/module-csp/Model/BlockCache.php
index f0469c32513..fac0beec51c 100644
--- a/vendor/magento/module-csp/Model/BlockCache.php
+++ b/vendor/magento/module-csp/Model/BlockCache.php
@@ -111,7 +111,7 @@ class BlockCache implements CacheInterface
                     ];
                 }
             }
-            $data = $this->serializer->serialize(['policies' => $policiesData, 'html' => $data]);
+            $data = $this->serializer->serialize(['policies' => $policiesData, 'html' => (string)$data]);
         }
 
         return $this->cache->save($data, $identifier, $tags, $lifeTime);
diff --git a/vendor/magento/module-csp/Model/Collector/CompositeMerger.php b/vendor/magento/module-csp/Model/Collector/CompositeMerger.php
new file mode 100644
index 00000000000..16430f1ff8a
--- /dev/null
+++ b/vendor/magento/module-csp/Model/Collector/CompositeMerger.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\Csp\Model\Collector;
+
+use Magento\Csp\Api\Data\PolicyInterface;
+
+/**
+ * Merges policies using different mergers.
+ */
+class CompositeMerger implements MergerInterface
+{
+    /**
+     * @var MergerInterface[]
+     */
+    private $mergers;
+
+    /**
+     * @param MergerInterface[] $mergers
+     */
+    public function __construct(array $mergers)
+    {
+        $this->mergers = $mergers;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function merge(PolicyInterface $policy1, PolicyInterface $policy2): PolicyInterface
+    {
+        foreach ($this->mergers as $merger) {
+            if ($merger->canMerge($policy1, $policy2)) {
+                return $merger->merge($policy1, $policy2);
+            }
+        }
+
+        throw new \RuntimeException('Cannot merge 2 policies of ' .get_class($policy1));
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function canMerge(PolicyInterface $policy1, PolicyInterface $policy2): bool
+    {
+        foreach ($this->mergers as $merger) {
+            if ($merger->canMerge($policy1, $policy2)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/vendor/magento/module-csp/Model/Collector/DynamicCollector.php b/vendor/magento/module-csp/Model/Collector/DynamicCollector.php
index 6478e9622f9..743f77c93f3 100644
--- a/vendor/magento/module-csp/Model/Collector/DynamicCollector.php
+++ b/vendor/magento/module-csp/Model/Collector/DynamicCollector.php
@@ -20,6 +20,19 @@ class DynamicCollector implements PolicyCollectorInterface
      */
     private $added = [];
 
+    /**
+     * @var MergerInterface
+     */
+    private $merger;
+
+    /**
+     * @param MergerInterface $merger
+     */
+    public function __construct(MergerInterface $merger)
+    {
+        $this->merger = $merger;
+    }
+
     /**
      * Add a policy for current page.
      *
@@ -28,7 +41,15 @@ class DynamicCollector implements PolicyCollectorInterface
      */
     public function add(PolicyInterface $policy): void
     {
-        $this->added[] = $policy;
+        if (array_key_exists($policy->getId(), $this->added)) {
+            if ($this->merger->canMerge($this->added[$policy->getId()], $policy)) {
+                $this->added[$policy->getId()] = $this->merger->merge($this->added[$policy->getId()], $policy);
+            } else {
+                throw new \RuntimeException('Cannot merge a policy of ' .get_class($policy));
+            }
+        } else {
+            $this->added[$policy->getId()] = $policy;
+        }
     }
 
     /**
@@ -36,6 +57,6 @@ class DynamicCollector implements PolicyCollectorInterface
      */
     public function collect(array $defaultPolicies = []): array
     {
-        return array_merge($defaultPolicies, $this->added);
+        return array_merge($defaultPolicies, array_values($this->added));
     }
 }
diff --git a/vendor/magento/module-csp/etc/di.xml b/vendor/magento/module-csp/etc/di.xml
index 7b1129a0e1a..238392fe1c8 100644
--- a/vendor/magento/module-csp/etc/di.xml
+++ b/vendor/magento/module-csp/etc/di.xml
@@ -15,6 +15,17 @@
         </arguments>
     </type>
     <preference for="Magento\Csp\Api\PolicyCollectorInterface" type="Magento\Csp\Model\CompositePolicyCollector" />
+    <preference for="Magento\Csp\Model\Collector\MergerInterface" type="Magento\Csp\Model\Collector\CompositeMerger" />
+    <type name="Magento\Csp\Model\Collector\CompositeMerger">
+        <arguments>
+            <argument name="mergers" xsi:type="array">
+                <item name="fetch" xsi:type="object">Magento\Csp\Model\Collector\FetchPolicyMerger</item>
+                <item name="flag" xsi:type="object">Magento\Csp\Model\Collector\FlagPolicyMerger</item>
+                <item name="plugins" xsi:type="object">Magento\Csp\Model\Collector\PluginTypesPolicyMerger</item>
+                <item name="sandbox" xsi:type="object">Magento\Csp\Model\Collector\SandboxPolicyMerger</item>
+            </argument>
+        </arguments>
+    </type>
     <type name="Magento\Csp\Model\CompositePolicyCollector">
         <arguments>
             <argument name="collectors" xsi:type="array">
@@ -24,10 +35,7 @@
                 <item name="dynamic" xsi:type="object" sortOrder="3">Magento\Csp\Model\Collector\DynamicCollector\Proxy</item>
             </argument>
             <argument name="mergers" xsi:type="array">
-                <item name="fetch" xsi:type="object">Magento\Csp\Model\Collector\FetchPolicyMerger</item>
-                <item name="flag" xsi:type="object">Magento\Csp\Model\Collector\FlagPolicyMerger</item>
-                <item name="plugins" xsi:type="object">Magento\Csp\Model\Collector\PluginTypesPolicyMerger</item>
-                <item name="sandbox" xsi:type="object">Magento\Csp\Model\Collector\SandboxPolicyMerger</item>
+                <item name="composite" xsi:type="object">Magento\Csp\Model\Collector\MergerInterface</item>
             </argument>
         </arguments>
     </type>
@@ -93,6 +101,7 @@
     <type name="Magento\Csp\Model\BlockCache">
         <arguments>
             <argument name="cache" xsi:type="object">configured_block_cache</argument>
+            <argument name="serializer" xsi:type="object">Magento\Framework\Serialize\Serializer\Serialize</argument>
         </arguments>
     </type>
     <type name="Magento\Framework\View\Element\Context">
