Skip to content

Commit 1090911

Browse files
authored
Merge pull request #7689 from magento-cia/2.4-bugfixes-052722
Bugfixes
2 parents faa7e0e + fbd543c commit 1090911

File tree

9 files changed

+1053
-15
lines changed

9 files changed

+1053
-15
lines changed

app/etc/di.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1973,4 +1973,5 @@
19731973
<argument name="defaultPageSize" xsi:type="number">20</argument>
19741974
</arguments>
19751975
</type>
1976+
<preference for="Magento\Framework\Filter\Input\PurifierInterface" type="Magento\Framework\Filter\Input\Purifier"/>
19761977
</config>

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"composer/composer": "^1.9 || ^2.0",
4242
"elasticsearch/elasticsearch": "~7.17.0",
4343
"guzzlehttp/guzzle": "^7.4.2",
44+
"ezyang/htmlpurifier": "^4.14",
4445
"laminas/laminas-captcha": "^2.12",
4546
"laminas/laminas-code": "~4.5.0",
4647
"laminas/laminas-db": "^2.15.0",

composer.lock

Lines changed: 51 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/internal/GnuFreeFont/gpl-3.0.txt

Lines changed: 674 additions & 0 deletions
Large diffs are not rendered by default.

lib/internal/Magento/Framework/Filter/Input/MaliciousCode.php

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,35 @@
11
<?php
22
/**
3-
* Filter for removing malicious code from HTML
4-
*
53
* Copyright © Magento, Inc. All rights reserved.
64
* See COPYING.txt for license details.
75
*/
6+
declare(strict_types=1);
87

98
namespace Magento\Framework\Filter\Input;
109

10+
use Magento\Framework\App\ObjectManager;
11+
1112
class MaliciousCode implements \Zend_Filter_Interface
1213
{
14+
/**
15+
* @var PurifierInterface|null $purifier
16+
*/
17+
private PurifierInterface $purifier;
18+
19+
/**
20+
* @param PurifierInterface|null $purifier
21+
*/
22+
public function __construct(?PurifierInterface $purifier = null)
23+
{
24+
$this->purifier = $purifier ?? ObjectManager::getInstance()->get(PurifierInterface::class);
25+
}
26+
1327
/**
1428
* Regular expressions for cutting malicious code
1529
*
1630
* @var string[]
1731
*/
18-
protected $_expressions = [
32+
protected array $_expressions = [
1933
//comments, must be first
2034
'/(\/\*.*\*\/)/Us',
2135
//tabs
@@ -41,15 +55,16 @@ class MaliciousCode implements \Zend_Filter_Interface
4155
* Filter value
4256
*
4357
* @param string|array $value
44-
* @return string|array Filtered value
58+
* @return string|array
4559
*/
4660
public function filter($value)
4761
{
4862
$replaced = 0;
4963
do {
5064
$value = preg_replace($this->_expressions, '', $value, -1, $replaced);
5165
} while ($replaced !== 0);
52-
return $value;
66+
67+
return $this->purifier->purify($value);
5368
}
5469

5570
/**
@@ -58,7 +73,7 @@ public function filter($value)
5873
* @param string $expression
5974
* @return $this
6075
*/
61-
public function addExpression($expression)
76+
public function addExpression(string $expression) :self
6277
{
6378
if (!in_array($expression, $this->_expressions)) {
6479
$this->_expressions[] = $expression;
@@ -72,7 +87,7 @@ public function addExpression($expression)
7287
* @param array $expressions
7388
* @return $this
7489
*/
75-
public function setExpressions(array $expressions)
90+
public function setExpressions(array $expressions) :self
7691
{
7792
$this->_expressions = $expressions;
7893
return $this;
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Framework\Filter\Input;
9+
10+
use HTMLPurifier;
11+
use HTMLPurifier_Config;
12+
use Magento\Framework\App\ObjectManager;
13+
14+
class Purifier implements PurifierInterface
15+
{
16+
public const CACHE_DEFINITION = 'Cache.DefinitionImpl';
17+
18+
/**
19+
* @var HTMLPurifier $purifier
20+
*/
21+
private HTMLPurifier $purifier;
22+
23+
/**
24+
* Purifier Constructor Call
25+
*/
26+
public function __construct()
27+
{
28+
$config = HTMLPurifier_Config::createDefault();
29+
$config->set(self::CACHE_DEFINITION, null);
30+
31+
$this->purifier = ObjectManager::getInstance()->create(HTMLPurifier::class, ['config' => $config]);
32+
}
33+
34+
/**
35+
* Purify Html Content from malicious code
36+
*
37+
* @param string|array $content
38+
* @return string|array
39+
*/
40+
public function purify($content)
41+
{
42+
return is_array($content) ? $this->purifier->purifyArray($content) : $this->purifier->purify($content);
43+
}
44+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Framework\Filter\Input;
9+
10+
interface PurifierInterface
11+
{
12+
/**
13+
* Purify Content from malicious code
14+
*
15+
* @param string|array $content
16+
* @return string|array
17+
*/
18+
public function purify($content);
19+
}

lib/internal/Magento/Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,37 @@
88
namespace Magento\Framework\Filter\Test\Unit\Input;
99

1010
use Magento\Framework\Filter\Input\MaliciousCode;
11+
use Magento\Framework\Filter\Input\PurifierInterface;
12+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
13+
use PHPUnit\Framework\MockObject\MockObject;
1114
use PHPUnit\Framework\TestCase;
1215

1316
class MaliciousCodeTest extends TestCase
1417
{
15-
/** @var MaliciousCode */
16-
protected $filter;
18+
/**
19+
* @var MockObject|PurifierInterface $purifier
20+
*/
21+
private MockObject $purifier;
22+
23+
/**
24+
* @var MaliciousCode $filter
25+
*/
26+
private MaliciousCode $filter;
1727

1828
protected function setUp(): void
1929
{
20-
$this->filter = new MaliciousCode();
30+
$this->purifier = $this->getMockBuilder(PurifierInterface::class)
31+
->disableOriginalConstructor()
32+
->onlyMethods(['purify'])
33+
->getMockForAbstractClass();
34+
35+
$objectManager = new ObjectManager($this);
36+
37+
$this->filter = $objectManager->getObject(
38+
MaliciousCode::class,
39+
['purifier' => $this->purifier]
40+
);
41+
2142
parent::setUp();
2243
}
2344

@@ -28,11 +49,11 @@ protected function setUp(): void
2849
*/
2950
public function testFilter($input, $expectedOutput)
3051
{
31-
$this->assertEquals(
32-
$expectedOutput,
33-
$this->filter->filter($input),
34-
'Malicious code is not filtered out correctly.'
35-
);
52+
$this->purifier->expects(self::atLeastOnce())
53+
->method('purify')
54+
->willReturn($expectedOutput);
55+
56+
self::assertEquals($expectedOutput, $this->filter->filter($input));
3657
}
3758

3859
/**
@@ -134,6 +155,11 @@ public function filterDataProvider()
134155
public function testAddExpression()
135156
{
136157
$customExpression = '/<\/?(customMalicious).*>/Uis';
158+
159+
$this->purifier->expects(self::atLeastOnce())
160+
->method('purify')
161+
->willReturn('Custom malicious tag is removed customMalicious');
162+
137163
$this->filter->addExpression($customExpression);
138164
$this->assertEquals(
139165
/** Tabs should be filtered out along with custom malicious code */
@@ -151,6 +177,11 @@ public function testAddExpression()
151177
public function testSetExpression()
152178
{
153179
$customExpression = '/<\/?(customMalicious).*>/Uis';
180+
181+
$this->purifier->expects(self::atLeastOnce())
182+
->method('purify')
183+
->willReturn("Custom \tmalicious tag\t\t is removed customMalicious");
184+
154185
$this->filter->setExpressions([$customExpression]);
155186
$this->assertEquals(
156187
/** Tabs should not be filtered out along with custom malicious code */

0 commit comments

Comments
 (0)