diff --git a/composer.json b/composer.json
index 3da6be3..5d90152 100644
--- a/composer.json
+++ b/composer.json
@@ -2,7 +2,7 @@
"name": "magento/magento-cloud-patches",
"description": "Provides critical fixes for Magento 2 Enterprise Edition",
"type": "magento2-component",
- "version": "1.1.1",
+ "version": "1.1.2",
"license": "OSL-3.0",
"repositories": {
"repo.magento.com": {
diff --git a/patches.json b/patches.json
index 637d3e1..8f41963 100644
--- a/patches.json
+++ b/patches.json
@@ -280,6 +280,18 @@
},
"Enhanced Layout Cache Efficiency (memory usage reduced)": {
">=2.4.4 <2.4.7": "MCLOUD-11514__enhanced_layout_cache_efficiency__2.4.6-p3.patch"
+ },
+ "Patch for CVE-2024-34102 - CosmicSting": {
+ ">=2.4.4 <2.4.4-p8": "MCLOUD-12969__Patch_for_CVE_2024_34102_CosmicSting__2.4.4.patch",
+ ">=2.4.5 <2.4.5-p7": "MCLOUD-12969__Patch_for_CVE_2024_34102_CosmicSting__2.4.5.patch",
+ ">=2.4.6 <2.4.6-p5": "MCLOUD-12969__Patch_for_CVE_2024_34102_CosmicSting__2.4.6.patch",
+ "2.4.7": "MCLOUD-12969__Patch_for_CVE_2024_34102_CosmicSting__2.4.7.patch"
+ },
+ "Patch for CVE-2024-34102 - KeyRotation": {
+ ">=2.4.4 <2.4.4-p10": "MCLOUD-12969__Patch_for_CVE_2024_34102_KeyRotation__2.4.4.patch",
+ ">=2.4.5 <2.4.5-p9": "MCLOUD-12969__Patch_for_CVE_2024_34102_KeyRotation__2.4.5.patch",
+ ">=2.4.6 <2.4.6-p7": "MCLOUD-12969__Patch_for_CVE_2024_34102_KeyRotation__2.4.6.patch",
+ ">=2.4.7 <2.4.7-p2": "MCLOUD-12969__Patch_for_CVE_2024_34102_KeyRotation__2.4.7.patch"
}
},
"magento/module-paypal": {
diff --git a/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_CosmicSting__2.4.4.patch b/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_CosmicSting__2.4.4.patch
new file mode 100644
index 0000000..5175edb
--- /dev/null
+++ b/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_CosmicSting__2.4.4.patch
@@ -0,0 +1,62 @@
+diff --git a/vendor/magento/theme-frontend-blank/i18n/en_US.csv b/vendor/magento/theme-frontend-blank/i18n/en_US.csv
+index a491a567a37..5e8bef787d2 100644
+--- a/vendor/magento/theme-frontend-blank/i18n/en_US.csv
++++ b/vendor/magento/theme-frontend-blank/i18n/en_US.csv
+@@ -4,3 +4,4 @@ Summary,Summary
+ Menu,Menu
+ Account,Account
+ Settings,Settings
++"Invalid data type","Invalid data type"
+diff --git a/vendor/magento/theme-frontend-luma/i18n/en_US.csv b/vendor/magento/theme-frontend-luma/i18n/en_US.csv
+index 7bf9e0afaf0..00493cc05ba 100644
+--- a/vendor/magento/theme-frontend-luma/i18n/en_US.csv
++++ b/vendor/magento/theme-frontend-luma/i18n/en_US.csv
+@@ -54,3 +54,4 @@ Footer,Footer
+ "Update to your %store_name shipment","Update to your %store_name shipment"
+ "Address Book","Address Book"
+ "Account Information","Account Information"
++"Invalid data type","Invalid data type"
+diff --git a/vendor/magento/framework/Webapi/ServiceInputProcessor.php b/vendor/magento/framework/Webapi/ServiceInputProcessor.php
+index 908a4e70140..cc019845b58 100644
+--- a/vendor/magento/framework/Webapi/ServiceInputProcessor.php
++++ b/vendor/magento/framework/Webapi/ServiceInputProcessor.php
+@@ -153,6 +153,7 @@ class ServiceInputProcessor implements ServicePayloadConverterInterface
+ * @return \Magento\Framework\Reflection\NameFinder
+ *
+ * @deprecated 100.1.0
++ * @see nothing
+ */
+ private function getNameFinder()
+ {
+@@ -261,6 +262,7 @@ class ServiceInputProcessor implements ServicePayloadConverterInterface
+ * @throws \Exception
+ * @throws SerializationException
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
++ * @SuppressWarnings(PHPMD.NPathComplexity)
+ */
+ protected function _createFromArray($className, $data)
+ {
+@@ -268,6 +270,12 @@ class ServiceInputProcessor implements ServicePayloadConverterInterface
+ // convert to string directly to avoid situations when $className is object
+ // which implements __toString method like \ReflectionObject
+ $className = (string) $className;
++ if (is_subclass_of($className, \SimpleXMLElement::class)
++ || is_subclass_of($className, \DOMElement::class)) {
++ throw new SerializationException(
++ new Phrase('Invalid data type')
++ );
++ }
+ $class = new ClassReflection($className);
+ if (is_subclass_of($className, self::EXTENSION_ATTRIBUTES_TYPE)) {
+ $className = substr($className, 0, -strlen('Interface'));
+diff --git a/vendor/magento/module-jwt-user-token/Model/SecretBasedJwksFactory.php b/vendor/magento/module-jwt-user-token/Model/SecretBasedJwksFactory.php
+--- a/vendor/magento/module-jwt-user-token/Model/SecretBasedJwksFactory.php (revision 022e64b08a88658667bc2d6b922eada2b7910965)
++++ b/vendor/magento/module-jwt-user-token/Model/SecretBasedJwksFactory.php (revision 8d2b0c1c6b421cdcd7f62a48a5edc9b0211d92a2)
+@@ -35,6 +35,7 @@
+ public function __construct(DeploymentConfig $deploymentConfig, JwkFactory $jwkFactory)
+ {
+ $this->keys = preg_split('/\s+/s', trim((string)$deploymentConfig->get('crypt/key')));
++ $this->keys = [end($this->keys)];
+ //Making sure keys are large enough.
+ foreach ($this->keys as &$key) {
+ $key = str_pad($key, 2048, '&', STR_PAD_BOTH);
diff --git a/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_CosmicSting__2.4.5.patch b/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_CosmicSting__2.4.5.patch
new file mode 100644
index 0000000..e5740c2
--- /dev/null
+++ b/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_CosmicSting__2.4.5.patch
@@ -0,0 +1,62 @@
+diff --git a/vendor/magento/theme-frontend-blank/i18n/en_US.csv b/vendor/magento/theme-frontend-blank/i18n/en_US.csv
+index a491a567a37..5e8bef787d2 100644
+--- a/vendor/magento/theme-frontend-blank/i18n/en_US.csv
++++ b/vendor/magento/theme-frontend-blank/i18n/en_US.csv
+@@ -4,3 +4,4 @@ Summary,Summary
+ Menu,Menu
+ Account,Account
+ Settings,Settings
++"Invalid data type","Invalid data type"
+diff --git a/vendor/magento/theme-frontend-luma/i18n/en_US.csv b/vendor/magento/theme-frontend-luma/i18n/en_US.csv
+index 7bf9e0afaf0..00493cc05ba 100644
+--- a/vendor/magento/theme-frontend-luma/i18n/en_US.csv
++++ b/vendor/magento/theme-frontend-luma/i18n/en_US.csv
+@@ -54,3 +54,4 @@ Footer,Footer
+ "Update to your %store_name shipment","Update to your %store_name shipment"
+ "Address Book","Address Book"
+ "Account Information","Account Information"
++"Invalid data type","Invalid data type"
+diff --git a/vendor/magento/framework/Webapi/ServiceInputProcessor.php b/vendor/magento/framework/Webapi/ServiceInputProcessor.php
+index a5e881f4be5..a60f1dd7ba1 100644
+--- a/vendor/magento/framework/Webapi/ServiceInputProcessor.php
++++ b/vendor/magento/framework/Webapi/ServiceInputProcessor.php
+@@ -153,6 +153,7 @@ class ServiceInputProcessor implements ServicePayloadConverterInterface
+ * @return \Magento\Framework\Reflection\NameFinder
+ *
+ * @deprecated 100.1.0
++ * @see nothing
+ */
+ private function getNameFinder()
+ {
+@@ -261,6 +262,7 @@ class ServiceInputProcessor implements ServicePayloadConverterInterface
+ * @throws \Exception
+ * @throws SerializationException
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
++ * @SuppressWarnings(PHPMD.NPathComplexity)
+ */
+ protected function _createFromArray($className, $data)
+ {
+@@ -268,6 +270,12 @@ class ServiceInputProcessor implements ServicePayloadConverterInterface
+ // convert to string directly to avoid situations when $className is object
+ // which implements __toString method like \ReflectionObject
+ $className = (string) $className;
++ if (is_subclass_of($className, \SimpleXMLElement::class)
++ || is_subclass_of($className, \DOMElement::class)) {
++ throw new SerializationException(
++ new Phrase('Invalid data type')
++ );
++ }
+ $class = new ClassReflection($className);
+ if (is_subclass_of($className, self::EXTENSION_ATTRIBUTES_TYPE)) {
+ $className = substr($className, 0, -strlen('Interface'));
+diff --git a/vendor/magento/module-jwt-user-token/Model/SecretBasedJwksFactory.php b/vendor/magento/module-jwt-user-token/Model/SecretBasedJwksFactory.php
+--- a/vendor/magento/module-jwt-user-token/Model/SecretBasedJwksFactory.php (revision 022e64b08a88658667bc2d6b922eada2b7910965)
++++ b/vendor/magento/module-jwt-user-token/Model/SecretBasedJwksFactory.php (revision 8d2b0c1c6b421cdcd7f62a48a5edc9b0211d92a2)
+@@ -35,6 +35,7 @@
+ public function __construct(DeploymentConfig $deploymentConfig, JwkFactory $jwkFactory)
+ {
+ $this->keys = preg_split('/\s+/s', trim((string)$deploymentConfig->get('crypt/key')));
++ $this->keys = [end($this->keys)];
+ //Making sure keys are large enough.
+ foreach ($this->keys as &$key) {
+ $key = str_pad($key, 2048, '&', STR_PAD_BOTH);
diff --git a/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_CosmicSting__2.4.6.patch b/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_CosmicSting__2.4.6.patch
new file mode 100644
index 0000000..1296cc0
--- /dev/null
+++ b/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_CosmicSting__2.4.6.patch
@@ -0,0 +1,46 @@
+diff --git a/vendor/magento/theme-frontend-blank/i18n/en_US.csv b/vendor/magento/theme-frontend-blank/i18n/en_US.csv
+index a491a567a37..5e8bef787d2 100644
+--- a/vendor/magento/theme-frontend-blank/i18n/en_US.csv
++++ b/vendor/magento/theme-frontend-blank/i18n/en_US.csv
+@@ -4,3 +4,4 @@ Summary,Summary
+ Menu,Menu
+ Account,Account
+ Settings,Settings
++"Invalid data type","Invalid data type"
+diff --git a/vendor/magento/theme-frontend-luma/i18n/en_US.csv b/vendor/magento/theme-frontend-luma/i18n/en_US.csv
+index 7bf9e0afaf0..00493cc05ba 100644
+--- a/vendor/magento/theme-frontend-luma/i18n/en_US.csv
++++ b/vendor/magento/theme-frontend-luma/i18n/en_US.csv
+@@ -54,3 +54,4 @@ Footer,Footer
+ "Update to your %store_name shipment","Update to your %store_name shipment"
+ "Address Book","Address Book"
+ "Account Information","Account Information"
++"Invalid data type","Invalid data type"
+diff --git a/vendor/magento/framework/Webapi/ServiceInputProcessor.php b/vendor/magento/framework/Webapi/ServiceInputProcessor.php
+index 9d7fd443508..65987772c23 100644
+--- a/vendor/magento/framework/Webapi/ServiceInputProcessor.php
++++ b/vendor/magento/framework/Webapi/ServiceInputProcessor.php
+@@ -275,6 +275,12 @@ class ServiceInputProcessor implements ServicePayloadConverterInterface
+ // convert to string directly to avoid situations when $className is object
+ // which implements __toString method like \ReflectionObject
+ $className = (string) $className;
++ if (is_subclass_of($className, \SimpleXMLElement::class)
++ || is_subclass_of($className, \DOMElement::class)) {
++ throw new SerializationException(
++ new Phrase('Invalid data type')
++ );
++ }
+ $class = new ClassReflection($className);
+ if (is_subclass_of($className, self::EXTENSION_ATTRIBUTES_TYPE)) {
+ $className = substr($className, 0, -strlen('Interface'));
+diff --git a/vendor/magento/module-jwt-user-token/Model/SecretBasedJwksFactory.php b/vendor/magento/module-jwt-user-token/Model/SecretBasedJwksFactory.php
+--- a/vendor/magento/module-jwt-user-token/Model/SecretBasedJwksFactory.php (revision 022e64b08a88658667bc2d6b922eada2b7910965)
++++ b/vendor/magento/module-jwt-user-token/Model/SecretBasedJwksFactory.php (revision 8d2b0c1c6b421cdcd7f62a48a5edc9b0211d92a2)
+@@ -35,6 +35,7 @@
+ public function __construct(DeploymentConfig $deploymentConfig, JwkFactory $jwkFactory)
+ {
+ $this->keys = preg_split('/\s+/s', trim((string)$deploymentConfig->get('crypt/key')));
++ $this->keys = [end($this->keys)];
+ //Making sure keys are large enough.
+ foreach ($this->keys as &$key) {
+ $key = str_pad($key, 2048, '&', STR_PAD_BOTH);
diff --git a/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_CosmicSting__2.4.7.patch b/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_CosmicSting__2.4.7.patch
new file mode 100644
index 0000000..4f23fb7
--- /dev/null
+++ b/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_CosmicSting__2.4.7.patch
@@ -0,0 +1,55 @@
+diff --git a/vendor/magento/theme-adminhtml-backend/i18n/en_US.csv b/vendor/magento/theme-adminhtml-backend/i18n/en_US.csv
+index 2708988e731..885d0056d4b 100644
+--- a/vendor/magento/theme-adminhtml-backend/i18n/en_US.csv
++++ b/vendor/magento/theme-adminhtml-backend/i18n/en_US.csv
+@@ -547,3 +547,4 @@ Dashboard,Dashboard
+ "Web Section","Web Section"
+ "Store Email Addresses Section","Store Email Addresses Section"
+ "Email to a Friend","Email to a Friend"
++"Invalid data type","Invalid data type"
+diff --git a/vendor/magento/theme-frontend-blank/i18n/en_US.csv b/vendor/magento/theme-frontend-blank/i18n/en_US.csv
+index 025866f654d..cc02ab5ac90 100644
+--- a/vendor/magento/theme-frontend-blank/i18n/en_US.csv
++++ b/vendor/magento/theme-frontend-blank/i18n/en_US.csv
+@@ -439,3 +439,4 @@ Summary,Summary
+ Test,Test
+ test,test
+ Two,Two
++"Invalid data type","Invalid data type"
+diff --git a/vendor/magento/theme-frontend-luma/i18n/en_US.csv b/vendor/magento/theme-frontend-luma/i18n/en_US.csv
+index e80cb58e679..3d0e8ab2650 100644
+--- a/vendor/magento/theme-frontend-luma/i18n/en_US.csv
++++ b/vendor/magento/theme-frontend-luma/i18n/en_US.csv
+@@ -489,3 +489,4 @@ Remove,Remove
+ Test,Test
+ test,test
+ Two,Two
++"Invalid data type","Invalid data type"
+diff --git a/vendor/magento/framework/Webapi/ServiceInputProcessor.php b/vendor/magento/framework/Webapi/ServiceInputProcessor.php
+index cd7960409e1..df31058ff32 100644
+--- a/vendor/magento/framework/Webapi/ServiceInputProcessor.php
++++ b/vendor/magento/framework/Webapi/ServiceInputProcessor.php
+@@ -278,6 +278,12 @@ class ServiceInputProcessor implements ServicePayloadConverterInterface, ResetAf
+ // convert to string directly to avoid situations when $className is object
+ // which implements __toString method like \ReflectionObject
+ $className = (string) $className;
++ if (is_subclass_of($className, \SimpleXMLElement::class)
++ || is_subclass_of($className, \DOMElement::class)) {
++ throw new SerializationException(
++ new Phrase('Invalid data type')
++ );
++ }
+ $class = new ClassReflection($className);
+ if (is_subclass_of($className, self::EXTENSION_ATTRIBUTES_TYPE)) {
+ $className = substr($className, 0, -strlen('Interface'));
+diff --git a/vendor/magento/module-jwt-user-token/Model/SecretBasedJwksFactory.php b/vendor/magento/module-jwt-user-token/Model/SecretBasedJwksFactory.php
+--- a/vendor/magento/module-jwt-user-token/Model/SecretBasedJwksFactory.php (revision 022e64b08a88658667bc2d6b922eada2b7910965)
++++ b/vendor/magento/module-jwt-user-token/Model/SecretBasedJwksFactory.php (revision 8d2b0c1c6b421cdcd7f62a48a5edc9b0211d92a2)
+@@ -35,6 +35,7 @@
+ public function __construct(DeploymentConfig $deploymentConfig, JwkFactory $jwkFactory)
+ {
+ $this->keys = preg_split('/\s+/s', trim((string)$deploymentConfig->get('crypt/key')));
++ $this->keys = [end($this->keys)];
+ //Making sure keys are large enough.
+ foreach ($this->keys as &$key) {
+ $key = str_pad($key, 2048, '&', STR_PAD_BOTH);
diff --git a/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_KeyRotation__2.4.4.patch b/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_KeyRotation__2.4.4.patch
new file mode 100644
index 0000000..94adc61
--- /dev/null
+++ b/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_KeyRotation__2.4.4.patch
@@ -0,0 +1,163 @@
+diff --git a/vendor/magento/module-encryption-key/Console/Command/UpdateEncryptionKeyCommand.php b/vendor/magento/module-encryption-key/Console/Command/UpdateEncryptionKeyCommand.php
+new file mode 100644
+index 0000000000000..8777f99139edc
+--- /dev/null
++++ b/vendor/magento/module-encryption-key/Console/Command/UpdateEncryptionKeyCommand.php
+@@ -0,0 +1,141 @@
++encryptor = $encryptor;
++ $this->cache = $cache;
++ $this->writer = $writer;
++ $this->random = $random;
++
++ parent::__construct();
++ }
++
++ /**
++ * @inheritDoc
++ */
++ protected function configure()
++ {
++ $this->setName('encryption:key:change');
++ $this->setDescription('Change the encryption key inside the env.php file.');
++ $this->addOption(
++ 'key',
++ 'k',
++ InputOption::VALUE_OPTIONAL,
++ 'Key has to be a 32 characters long string. If not provided, a random key will be generated.'
++ );
++
++ parent::configure();
++ }
++
++ /**
++ * @inheritDoc
++ */
++ protected function execute(InputInterface $input, OutputInterface $output)
++ {
++ try {
++ $key = $input->getOption('key');
++
++ if (!empty($key)) {
++ $this->encryptor->validateKey($key);
++ }
++
++ $this->updateEncryptionKey($key);
++ $this->cache->clean();
++
++ $output->writeln('Encryption key has been updated successfully.');
++
++ return Cli::RETURN_SUCCESS;
++ } catch (\Exception $e) {
++ $output->writeln('' . $e->getMessage() . '');
++ return Cli::RETURN_FAILURE;
++ }
++ }
++
++ /**
++ * Update encryption key
++ *
++ * @param string|null $key
++ * @return void
++ * @throws FileSystemException
++ */
++ private function updateEncryptionKey(string $key = null): void
++ {
++ // prepare new key, encryptor and new configuration segment
++ if (!$this->writer->checkIfWritable()) {
++ throw new FileSystemException(__('Deployment configuration file is not writable.'));
++ }
++
++ if (null === $key) {
++ // md5() here is not for cryptographic use. It used for generate encryption key itself
++ // and do not encrypt any passwords
++ // phpcs:ignore Magento2.Security.InsecureFunction
++ $key = md5($this->random->getRandomString(ConfigOptionsListConstants::STORE_KEY_RANDOM_STRING_SIZE));
++ }
++
++ $this->encryptor->setNewKey($key);
++
++ $encryptSegment = new ConfigData(ConfigFilePool::APP_ENV);
++ $encryptSegment->set(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY, $this->encryptor->exportKeys());
++
++ $configData = [$encryptSegment->getFileKey() => $encryptSegment->getData()];
++
++ $this->writer->saveConfig($configData);
++ }
++}
+diff --git a/vendor/magento/module-encryption-key/etc/di.xml b/vendor/magento/module-encryption-key/etc/di.xml
+index b4e471f4e40ef..495234759a7f8 100644
+--- a/vendor/magento/module-encryption-key/etc/di.xml
++++ b/vendor/magento/module-encryption-key/etc/di.xml
+@@ -11,4 +11,11 @@
+ Magento\Config\Model\Config\Structure\Proxy
+
+
++
++
++
++ - Magento\EncryptionKey\Console\Command\UpdateEncryptionKeyCommand
++
++
++
+
diff --git a/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_KeyRotation__2.4.5.patch b/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_KeyRotation__2.4.5.patch
new file mode 100644
index 0000000..29adfc3
--- /dev/null
+++ b/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_KeyRotation__2.4.5.patch
@@ -0,0 +1,162 @@
+diff --git a/vendor/magento/module-encryption-key/Console/Command/UpdateEncryptionKeyCommand.php b/vendor/magento/module-encryption-key/Console/Command/UpdateEncryptionKeyCommand.php
+new file mode 100644
+index 0000000000000..351379552e104
+--- /dev/null
++++ b/vendor/magento/module-encryption-key/Console/Command/UpdateEncryptionKeyCommand.php
+@@ -0,0 +1,140 @@
++encryptor = $encryptor;
++ $this->cache = $cache;
++ $this->writer = $writer;
++ $this->random = $random;
++
++ parent::__construct();
++ }
++
++ /**
++ * @inheritDoc
++ */
++ protected function configure()
++ {
++ $this->setName('encryption:key:change');
++ $this->setDescription('Change the encryption key inside the env.php file.');
++ $this->addOption(
++ 'key',
++ 'k',
++ InputOption::VALUE_OPTIONAL,
++ 'Key has to be a 32 characters long string. If not provided, a random key will be generated.'
++ );
++
++ parent::configure();
++ }
++
++ /**
++ * @inheritDoc
++ */
++ protected function execute(InputInterface $input, OutputInterface $output)
++ {
++ try {
++ $key = $input->getOption('key');
++
++ if (!empty($key)) {
++ $this->encryptor->validateKey($key);
++ }
++
++ $this->updateEncryptionKey($key);
++ $this->cache->clean();
++
++ $output->writeln('Encryption key has been updated successfully.');
++
++ return Cli::RETURN_SUCCESS;
++ } catch (\Exception $e) {
++ $output->writeln('' . $e->getMessage() . '');
++ return Cli::RETURN_FAILURE;
++ }
++ }
++
++ /**
++ * Update encryption key
++ *
++ * @param string|null $key
++ * @return void
++ * @throws FileSystemException
++ */
++ private function updateEncryptionKey(string $key = null): void
++ {
++ // prepare new key, encryptor and new configuration segment
++ if (!$this->writer->checkIfWritable()) {
++ throw new FileSystemException(__('Deployment configuration file is not writable.'));
++ }
++
++ if (null === $key) {
++ // md5() here is not for cryptographic use. It used for generate encryption key itself
++ // and do not encrypt any passwords
++ // phpcs:ignore Magento2.Security.InsecureFunction
++ $key = md5($this->random->getRandomString(ConfigOptionsListConstants::STORE_KEY_RANDOM_STRING_SIZE));
++ }
++ $this->encryptor->setNewKey($key);
++
++ $encryptSegment = new ConfigData(ConfigFilePool::APP_ENV);
++ $encryptSegment->set(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY, $this->encryptor->exportKeys());
++
++ $configData = [$encryptSegment->getFileKey() => $encryptSegment->getData()];
++
++ $this->writer->saveConfig($configData);
++ }
++}
+diff --git a/vendor/magento/module-encryption-key/etc/di.xml b/vendor/magento/module-encryption-key/etc/di.xml
+index b4e471f4e40ef..495234759a7f8 100644
+--- a/vendor/magento/module-encryption-key/etc/di.xml
++++ b/vendor/magento/module-encryption-key/etc/di.xml
+@@ -11,4 +11,11 @@
+ Magento\Config\Model\Config\Structure\Proxy
+
+
++
++
++
++ - Magento\EncryptionKey\Console\Command\UpdateEncryptionKeyCommand
++
++
++
+
diff --git a/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_KeyRotation__2.4.6.patch b/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_KeyRotation__2.4.6.patch
new file mode 100644
index 0000000..c5ba438
--- /dev/null
+++ b/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_KeyRotation__2.4.6.patch
@@ -0,0 +1,159 @@
+diff --git a/vendor/magento/module-encryption-key/Console/Command/UpdateEncryptionKeyCommand.php b/vendor/magento/module-encryption-key/Console/Command/UpdateEncryptionKeyCommand.php
+new file mode 100644
+index 0000000000000..0e4995b847893
+--- /dev/null
++++ b/vendor/magento/module-encryption-key/Console/Command/UpdateEncryptionKeyCommand.php
+@@ -0,0 +1,137 @@
++encryptor = $encryptor;
++ $this->cache = $cache;
++ $this->writer = $writer;
++ $this->random = $random;
++
++ parent::__construct();
++ }
++
++ /**
++ * @inheritDoc
++ */
++ protected function configure()
++ {
++ $this->setName('encryption:key:change');
++ $this->setDescription('Change the encryption key inside the env.php file.');
++ $this->addOption(
++ 'key',
++ 'k',
++ InputOption::VALUE_OPTIONAL,
++ 'Key has to be a 32 characters long string. If not provided, a random key will be generated.'
++ );
++
++ parent::configure();
++ }
++
++ /**
++ * @inheritDoc
++ */
++ protected function execute(InputInterface $input, OutputInterface $output)
++ {
++ try {
++ $key = $input->getOption('key');
++
++ if (!empty($key)) {
++ $this->encryptor->validateKey($key);
++ }
++
++ $this->updateEncryptionKey($key);
++ $this->cache->clean();
++
++ $output->writeln('Encryption key has been updated successfully.');
++
++ return Command::SUCCESS;
++ } catch (\Exception $e) {
++ $output->writeln('' . $e->getMessage() . '');
++ return Command::FAILURE;
++ }
++ }
++
++ /**
++ * Update encryption key
++ *
++ * @param string|null $key
++ * @return void
++ * @throws FileSystemException
++ */
++ private function updateEncryptionKey(string $key = null): void
++ {
++ // prepare new key, encryptor and new configuration segment
++ if (!$this->writer->checkIfWritable()) {
++ throw new FileSystemException(__('Deployment configuration file is not writable.'));
++ }
++
++ if (null === $key) {
++ // md5() here is not for cryptographic use. It used for generate encryption key itself
++ // and do not encrypt any passwords
++ // phpcs:ignore Magento2.Security.InsecureFunction
++ $key = md5($this->random->getRandomString(ConfigOptionsListConstants::STORE_KEY_RANDOM_STRING_SIZE));
++ }
++
++ $this->encryptor->setNewKey($key);
++
++ $encryptSegment = new ConfigData(ConfigFilePool::APP_ENV);
++ $encryptSegment->set(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY, $this->encryptor->exportKeys());
++
++ $configData = [$encryptSegment->getFileKey() => $encryptSegment->getData()];
++
++ $this->writer->saveConfig($configData);
++ }
++}
+diff --git a/vendor/magento/module-encryption-key/etc/di.xml b/vendor/magento/module-encryption-key/etc/di.xml
+index b4e471f4e40ef..495234759a7f8 100644
+--- a/vendor/magento/module-encryption-key/etc/di.xml
++++ b/vendor/magento/module-encryption-key/etc/di.xml
+@@ -11,4 +11,11 @@
+ Magento\Config\Model\Config\Structure\Proxy
+
+
++
++
++
++ - Magento\EncryptionKey\Console\Command\UpdateEncryptionKeyCommand
++
++
++
+
diff --git a/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_KeyRotation__2.4.7.patch b/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_KeyRotation__2.4.7.patch
new file mode 100644
index 0000000..0c8e1fc
--- /dev/null
+++ b/patches/MCLOUD-12969__Patch_for_CVE_2024_34102_KeyRotation__2.4.7.patch
@@ -0,0 +1,157 @@
+diff --git a/vendor/magento/module-encryption-key/Console/Command/UpdateEncryptionKeyCommand.php b/vendor/magento/module-encryption-key/Console/Command/UpdateEncryptionKeyCommand.php
+new file mode 100644
+index 0000000000000..cd6ffb4323163
+--- /dev/null
++++ b/vendor/magento/module-encryption-key/Console/Command/UpdateEncryptionKeyCommand.php
+@@ -0,0 +1,135 @@
++encryptor = $encryptor;
++ $this->cache = $cache;
++ $this->writer = $writer;
++ $this->random = $random;
++
++ parent::__construct();
++ }
++
++ /**
++ * @inheritDoc
++ */
++ protected function configure()
++ {
++ $this->setName('encryption:key:change');
++ $this->setDescription('Change the encryption key inside the env.php file.');
++ $this->addOption(
++ 'key',
++ 'k',
++ InputOption::VALUE_OPTIONAL,
++ 'Key has to be a 32 characters long string. If not provided, a random key will be generated.'
++ );
++
++ parent::configure();
++ }
++
++ /**
++ * @inheritDoc
++ */
++ protected function execute(InputInterface $input, OutputInterface $output)
++ {
++ try {
++ $key = $input->getOption('key');
++
++ if (!empty($key)) {
++ $this->encryptor->validateKey($key);
++ }
++
++ $this->updateEncryptionKey($key);
++ $this->cache->clean();
++
++ $output->writeln('Encryption key has been updated successfully.');
++
++ return Command::SUCCESS;
++ } catch (\Exception $e) {
++ $output->writeln('' . $e->getMessage() . '');
++ return Command::FAILURE;
++ }
++ }
++
++ /**
++ * Update encryption key
++ *
++ * @param string|null $key
++ * @return void
++ * @throws FileSystemException
++ */
++ private function updateEncryptionKey(string $key = null): void
++ {
++ // prepare new key, encryptor and new configuration segment
++ if (!$this->writer->checkIfWritable()) {
++ throw new FileSystemException(__('Deployment configuration file is not writable.'));
++ }
++
++ if (null === $key) {
++ $key = ConfigOptionsListConstants::STORE_KEY_ENCODED_RANDOM_STRING_PREFIX .
++ $this->random->getRandomBytes(ConfigOptionsListConstants::STORE_KEY_RANDOM_STRING_SIZE);
++ }
++
++ $this->encryptor->setNewKey($key);
++
++ $encryptSegment = new ConfigData(ConfigFilePool::APP_ENV);
++ $encryptSegment->set(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY, $this->encryptor->exportKeys());
++
++ $configData = [$encryptSegment->getFileKey() => $encryptSegment->getData()];
++
++ $this->writer->saveConfig($configData);
++ }
++}
+diff --git a/vendor/magento/module-encryption-key/etc/di.xml b/vendor/magento/module-encryption-key/etc/di.xml
+index b4e471f4e40ef..495234759a7f8 100644
+--- a/vendor/magento/module-encryption-key/etc/di.xml
++++ b/vendor/magento/module-encryption-key/etc/di.xml
+@@ -11,4 +11,11 @@
+ Magento\Config\Model\Config\Structure\Proxy
+
+
++
++
++
++ - Magento\EncryptionKey\Console\Command\UpdateEncryptionKeyCommand
++
++
++
+