Skip to content

Commit c71ea49

Browse files
authored
Merge pull request #6803 from magento-cia/cia-2.4.3-bugfixes-4222021
cia-bugfixes-2.4.3
2 parents 8528e93 + 765f26f commit c71ea49

File tree

32 files changed

+1015
-115
lines changed

32 files changed

+1015
-115
lines changed

app/code/Magento/Backup/Model/Fs/Collection.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\Backup\Model\Fs;
79

810
use Magento\Framework\App\Filesystem\DirectoryList;
@@ -88,12 +90,17 @@ public function __construct(
8890
* Create .htaccess file and deny backups directory access from web
8991
*
9092
* @return void
93+
* @throws \Magento\Framework\Exception\FileSystemException
9194
*/
9295
protected function _hideBackupsForApache()
9396
{
9497
$filename = '.htaccess';
95-
if (!$this->_varDirectory->isFile($filename)) {
96-
$this->_varDirectory->writeFile($filename, 'deny from all');
98+
$driver = $this->_varDirectory->getDriver();
99+
$absolutePath = $driver->getAbsolutePath($this->_varDirectory->getAbsolutePath(), $filename);
100+
if (!$driver->isFile($absolutePath)) {
101+
$resource = $driver->fileOpen($absolutePath, 'w+');
102+
$driver->fileWrite($resource, 'deny from all');
103+
$driver->fileClose($resource);
97104
}
98105
}
99106

app/code/Magento/Backup/Test/Unit/Model/Fs/CollectionTest.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,15 @@ public function testConstructor()
3434
)->disableOriginalConstructor()
3535
->getMock();
3636
$backupData->expects($this->any())->method('getExtensions')->willReturn([]);
37-
37+
$driver = $this->getMockBuilder(
38+
Filesystem\DriverInterface::class
39+
)->disableOriginalConstructor()
40+
->getMock();
3841
$directoryWrite->expects($this->any())->method('create')->with('backups');
39-
$directoryWrite->expects($this->any())->method('getAbsolutePath')->with('backups');
42+
$directoryWrite->expects($this->any())->method('getAbsolutePath')->willReturn('');
43+
$directoryWrite->expects($this->at(3))->method('getAbsolutePath')->with('backups');
4044
$directoryWrite->expects($this->any())->method('isDirectory')->willReturn(true);
45+
$directoryWrite->expects($this->any())->method('getDriver')->willReturn($driver);
4146
$targetDirectory = $this->getMockBuilder(TargetDirectory::class)
4247
->disableOriginalConstructor()
4348
->getMock();

app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
67

78
namespace Magento\Catalog\Model\Product\Option\Type\File;
89

910
use Magento\Catalog\Model\Product;
10-
use Magento\Framework\App\Filesystem\DirectoryList;
1111
use Magento\Catalog\Model\Product\Exception as ProductException;
12+
use Magento\Framework\App\Filesystem\DirectoryList;
13+
use Magento\Framework\App\ObjectManager;
1214
use Magento\Framework\Exception\LocalizedException;
1315
use Magento\Framework\Math\Random;
14-
use Magento\Framework\App\ObjectManager;
1516
use Magento\MediaStorage\Model\File\Uploader;
1617

1718
/**
@@ -254,8 +255,12 @@ protected function initFilesystem()
254255

255256
// Directory listing and hotlink secure
256257
$path = $this->path . '/.htaccess';
257-
if (!$this->mediaDirectory->isFile($path)) {
258-
$this->mediaDirectory->writeFile($path, "Order deny,allow\nDeny from all");
258+
$driver = $this->mediaDirectory->getDriver();
259+
$absolutePath = $driver->getAbsolutePath($this->mediaDirectory->getAbsolutePath(), $path);
260+
if (!$driver->isFile($absolutePath)) {
261+
$resource = $driver->fileOpen($absolutePath, 'w+');
262+
$driver->fileWrite($resource, "Order deny,allow\nDeny from all");
263+
$driver->fileClose($resource);
259264
}
260265
}
261266

app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorInfo.php

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,22 @@
66

77
namespace Magento\Catalog\Model\Product\Option\Type\File;
88

9+
use Magento\Framework\App\Config\ScopeConfigInterface;
10+
use Magento\Framework\Exception\InputException;
11+
use Magento\Framework\Exception\LocalizedException;
12+
use Magento\Framework\File\Size;
13+
use Magento\Framework\Filesystem;
14+
use Magento\Framework\Filesystem\Io\File as IoFile;
15+
use Magento\MediaStorage\Helper\File\Storage\Database;
16+
use Magento\MediaStorage\Model\File\Validator\NotProtectedExtension;
17+
918
/**
1019
* Validator for existing files.
1120
*/
1221
class ValidatorInfo extends Validator
1322
{
1423
/**
15-
* @var \Magento\MediaStorage\Helper\File\Storage\Database
24+
* @var Database
1625
*/
1726
protected $coreFileStorageDatabase;
1827

@@ -36,24 +45,39 @@ class ValidatorInfo extends Validator
3645
*/
3746
protected $fileRelativePath;
3847

48+
/**
49+
* @var IoFile
50+
*/
51+
private $ioFile;
52+
/**
53+
* @var NotProtectedExtension
54+
*/
55+
private $fileValidator;
56+
3957
/**
4058
* Construct method
4159
*
42-
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
43-
* @param \Magento\Framework\Filesystem $filesystem
44-
* @param \Magento\Framework\File\Size $fileSize
45-
* @param \Magento\MediaStorage\Helper\File\Storage\Database $coreFileStorageDatabase
60+
* @param ScopeConfigInterface $scopeConfig
61+
* @param Filesystem $filesystem
62+
* @param Size $fileSize
63+
* @param Database $coreFileStorageDatabase
4664
* @param ValidateFactory $validateFactory
65+
* @param NotProtectedExtension $fileValidator
66+
* @param IoFile $ioFile
4767
*/
4868
public function __construct(
49-
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
50-
\Magento\Framework\Filesystem $filesystem,
51-
\Magento\Framework\File\Size $fileSize,
52-
\Magento\MediaStorage\Helper\File\Storage\Database $coreFileStorageDatabase,
53-
\Magento\Catalog\Model\Product\Option\Type\File\ValidateFactory $validateFactory
69+
ScopeConfigInterface $scopeConfig,
70+
Filesystem $filesystem,
71+
Size $fileSize,
72+
Database $coreFileStorageDatabase,
73+
ValidateFactory $validateFactory,
74+
NotProtectedExtension $fileValidator,
75+
IoFile $ioFile
5476
) {
5577
$this->coreFileStorageDatabase = $coreFileStorageDatabase;
5678
$this->validateFactory = $validateFactory;
79+
$this->fileValidator = $fileValidator;
80+
$this->ioFile = $ioFile;
5781
parent::__construct($scopeConfig, $filesystem, $fileSize);
5882
}
5983

@@ -94,27 +118,42 @@ public function validate($optionValue, $option)
94118
$validatorChain = $this->validateFactory->create();
95119
try {
96120
$validatorChain = $this->buildImageValidator($validatorChain, $option, $this->fileFullPath);
97-
} catch (\Magento\Framework\Exception\InputException $notImage) {
121+
} catch (InputException $notImage) {
98122
return false;
99123
}
100124

101-
$result = false;
102-
if ($validatorChain->isValid($this->fileFullPath, $optionValue['title'])) {
103-
$result = $this->rootDirectory->isReadable($this->fileRelativePath)
125+
if ($this->validatePath($optionValue) && $validatorChain->isValid($this->fileFullPath, $optionValue['title'])) {
126+
return $this->rootDirectory->isReadable($this->fileRelativePath)
104127
&& isset($optionValue['secret_key'])
105128
&& $this->buildSecretKey($this->fileRelativePath) == $optionValue['secret_key'];
106-
} elseif ($validatorChain->getErrors()) {
129+
} else {
107130
$errors = $this->getValidatorErrors($validatorChain->getErrors(), $optionValue, $option);
108-
109131
if (count($errors) > 0) {
110-
throw new \Magento\Framework\Exception\LocalizedException(__(implode("\n", $errors)));
132+
throw new LocalizedException(__(implode("\n", $errors)));
111133
}
112-
} else {
113-
throw new \Magento\Framework\Exception\LocalizedException(
134+
throw new LocalizedException(
114135
__("The product's required option(s) weren't entered. Make sure the options are entered and try again.")
115136
);
116137
}
117-
return $result;
138+
}
139+
140+
/**
141+
* Validate quote_path and order_path.
142+
*
143+
* @param array $optionValuePath
144+
* @return bool
145+
*/
146+
private function validatePath(array $optionValuePath): bool
147+
{
148+
foreach ([$optionValuePath['quote_path'], $optionValuePath['order_path']] as $path) {
149+
$pathInfo = $this->ioFile->getPathInfo($path);
150+
if (isset($pathInfo['extension'])) {
151+
if (!$this->fileValidator->isValid($pathInfo['extension'])) {
152+
return false;
153+
}
154+
}
155+
}
156+
return true;
118157
}
119158

120159
/**

app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ public function createDirectory($name, $path)
436436
);
437437
}
438438

439-
$relativePath = $this->_directory->getRelativePath($path);
439+
$relativePath = (string) $this->_directory->getRelativePath($path);
440440
if (!$this->_directory->isDirectory($relativePath) || !$this->_directory->isWritable($relativePath)) {
441441
$path = $this->_cmsWysiwygImages->getStorageRoot();
442442
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
/**
8+
* System config email field backend model
9+
*/
10+
declare(strict_types=1);
11+
12+
namespace Magento\Security\Block\Config\Backend\Session;
13+
14+
use Magento\Backend\Block\Template\Context;
15+
use Magento\Config\Block\System\Config\Form\Field;
16+
use Magento\Framework\Data\Form\Element\AbstractElement;
17+
use Magento\Framework\Exception\ValidatorException;
18+
use Magento\Framework\Serialize\Serializer\Json;
19+
20+
/**
21+
* Backend Model for Max Session Size
22+
*/
23+
class SessionSize extends Field
24+
{
25+
/**
26+
* @var Json
27+
*/
28+
private $json;
29+
30+
/**
31+
* @param Context $context
32+
* @param Json $json
33+
* @param array $data
34+
*/
35+
public function __construct(
36+
Context $context,
37+
Json $json,
38+
array $data = []
39+
) {
40+
parent::__construct($context, $data);
41+
$this->json = $json;
42+
}
43+
44+
/**
45+
* {@inheritdoc}
46+
* @throws ValidatorException
47+
*/
48+
protected function _getElementHtml(AbstractElement $element)
49+
{
50+
$html = parent::_getElementHtml($element);
51+
$originalData = $element->getOriginalData();
52+
$maxSessionSizeAdminSelector = '#' . $element->getHtmlId();
53+
$jsString = '<script type="text/x-magento-init"> {"' .
54+
$maxSessionSizeAdminSelector . '": {
55+
"Magento_Security/js/system/config/session-size": {"modalTitleText": ' .
56+
$this->json->serialize(__($originalData['modal_title_text'])) . ', "modalContentBody": ' .
57+
$this->json->serialize($this->getModalContentBody($originalData['modal_content_body_path']))
58+
. '}}}</script>';
59+
60+
$html .= $jsString;
61+
return $html;
62+
}
63+
64+
/**
65+
* Get HTML for the modal content body when user switches to disable
66+
*
67+
* @param string $templatePath
68+
* @return string
69+
* @throws ValidatorException
70+
*/
71+
private function getModalContentBody(string $templatePath)
72+
{
73+
$templateFileName = $this->getTemplateFile($templatePath);
74+
75+
return $this->fetchView($templateFileName);
76+
}
77+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
/**
8+
* System config email field backend model
9+
*/
10+
declare(strict_types=1);
11+
12+
namespace Magento\Security\Model\Config\Backend\Session;
13+
14+
use Magento\Framework\App\Config\Value;
15+
16+
/**
17+
* Backend Model for Max Session Size
18+
*/
19+
class SessionSize extends Value
20+
{
21+
/**
22+
* Handles the before save event
23+
*
24+
* @return $this
25+
*/
26+
public function beforeSave()
27+
{
28+
$value = $this->getValue();
29+
if ($value === '0') {
30+
$value = 0;
31+
} else {
32+
$value = (int)$value;
33+
if ($value === null || $value <= 0) {
34+
$value = 256000;
35+
}
36+
}
37+
$this->setValue((string)$value);
38+
return $this;
39+
}
40+
}

app/code/Magento/Security/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"require": {
88
"php": "~7.3.0||~7.4.0",
99
"magento/framework": "*",
10+
"magento/module-config": "*",
1011
"magento/module-backend": "*",
1112
"magento/module-store": "*",
1213
"magento/module-user": "*"

app/code/Magento/Security/etc/adminhtml/system.xml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,29 @@
3636
</field>
3737
</group>
3838
</section>
39+
<section id="system">
40+
<group id="security" translate="label" type="text" sortOrder="60" showInDefault="1" showInWebsite="1">
41+
<label>Security</label>
42+
<field id="max_session_size_admin" translate="label" type="text" sortOrder="1" showInDefault="1" canRestore="1">
43+
<label>Max Session Size in Admin</label>
44+
<attribute type="modal_title_text">Are You Sure About Your Max Session Size in Admin Settings?</attribute>
45+
<attribute type="modal_content_body_path">Magento_Security::system/config/session_size_admin/modal_content_body.phtml</attribute>
46+
<validate>required-entry validate-zero-or-greater validate-digits</validate>
47+
<frontend_model>Magento\Security\Block\Config\Backend\Session\SessionSize</frontend_model>
48+
<backend_model>Magento\Security\Model\Config\Backend\Session\SessionSize</backend_model>
49+
<comment>Limit the maximum session size in bytes. Use 0 to disable.</comment>
50+
</field>
51+
<field id="max_session_size_storefront" translate="label" type="text" sortOrder="2" showInDefault="1" canRestore="1">
52+
<label>Max Session Size in Storefront</label>
53+
<attribute type="modal_title_text">Are You Sure About Your Max Session Size in Storefront Settings?</attribute>
54+
<attribute type="modal_content_body_path">Magento_Security::system/config/session_size_storefront/modal_content_body.phtml</attribute>
55+
<validate>required-entry validate-zero-or-greater validate-digits</validate>
56+
<frontend_model>Magento\Security\Block\Config\Backend\Session\SessionSize</frontend_model>
57+
<backend_model>Magento\Security\Model\Config\Backend\Session\SessionSize</backend_model>
58+
<comment>Limit the maximum session size in bytes. Use 0 to disable.</comment>
59+
</field>
60+
</group>
61+
</section>
3962
<section id="customer">
4063
<group id="password">
4164
<field id="password_reset_protection_type" translate="label" type="select" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">

app/code/Magento/Security/etc/config.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616
<session_lifetime>900</session_lifetime>
1717
</security>
1818
</admin>
19+
<system>
20+
<security>
21+
<max_session_size_admin>256000</max_session_size_admin>
22+
<max_session_size_storefront>256000</max_session_size_storefront>
23+
</security>
24+
</system>
1925
<customer>
2026
<password>
2127
<password_reset_protection_type>1</password_reset_protection_type>

0 commit comments

Comments
 (0)