Skip to content

Commit 788adef

Browse files
committed
MC-10871: [Sec] XSS Injection in HTML Code Content Type
- Filter HTML content types and encode their values
1 parent c6979e1 commit 788adef

File tree

2 files changed

+28
-11
lines changed

2 files changed

+28
-11
lines changed

app/code/Magento/PageBuilder/Model/Stage/ScriptFilter.php renamed to app/code/Magento/PageBuilder/Model/Stage/HtmlFilter.php

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@
1111
use Psr\Log\LoggerInterface;
1212

1313
/**
14-
* Filters script tags from stage output
14+
* Filters HTML from stage output
1515
*
1616
* @api
1717
*/
18-
class ScriptFilter
18+
class HtmlFilter
1919
{
2020
/**
2121
* @var LoggerInterface
2222
*/
2323
private $loggerInterface;
2424

2525
/**
26-
* ScriptFilter constructor.
26+
* HtmlFilter constructor.
2727
* @param LoggerInterface $loggerInterface
2828
*/
2929
public function __construct(
@@ -33,12 +33,12 @@ public function __construct(
3333
}
3434

3535
/**
36-
* Remove script tag from html
36+
* Filter HTML text to remove script tags and encode HTML content types
3737
*
3838
* @param string $content
3939
* @return string
4040
*/
41-
public function removeScriptTags(string $content): string
41+
public function filterHtml(string $content): string
4242
{
4343
$dom = new \DOMDocument();
4444
try {
@@ -49,9 +49,26 @@ public function removeScriptTags(string $content): string
4949
$this->loggerInterface->critical($e->getMessage());
5050
}
5151
libxml_use_internal_errors($previous);
52+
// Remove all <script /> tags from output
5253
foreach (iterator_to_array($dom->getElementsByTagName('script')) as $item) {
5354
$item->parentNode->removeChild($item);
5455
}
56+
$xpath = new \DOMXPath($dom);
57+
$htmlContentTypes = $xpath->query('//*[@data-role="html"]');
58+
foreach ($htmlContentTypes as $htmlContentType) {
59+
/* @var \DOMElement $htmlContentType */
60+
$innerHTML= '';
61+
$children = $htmlContentType->childNodes;
62+
foreach ($children as $child) {
63+
$innerHTML .= $child->ownerDocument->saveXML($child);
64+
}
65+
$htmlContentType->removeAttribute("data-role");
66+
$htmlContentType->setAttribute(
67+
"class",
68+
$htmlContentType->getAttribute("class") . " placeholder-html-code"
69+
);
70+
$htmlContentType->nodeValue = htmlentities($innerHTML);
71+
}
5572
return $dom->saveHTML();
5673
}
5774
}

app/code/Magento/PageBuilder/Model/Stage/Renderer/CmsStaticBlock.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,28 +33,28 @@ class CmsStaticBlock implements \Magento\PageBuilder\Model\Stage\RendererInterfa
3333
private $loggerInterface;
3434

3535
/**
36-
* @var \Magento\PageBuilder\Model\Stage\ScriptFilter
36+
* @var \Magento\PageBuilder\Model\Stage\HtmlFilter
3737
*/
38-
private $scriptFilter;
38+
private $htmlFilter;
3939

4040
/**
4141
* CmsStaticBlock constructor.
4242
*
4343
* @param \Magento\Cms\Model\ResourceModel\Block\CollectionFactory $blockCollectionFactory
4444
* @param WidgetDirective $widgetDirectiveRenderer
4545
* @param LoggerInterface $loggerInterface
46-
* @param \Magento\PageBuilder\Model\Stage\ScriptFilter $scriptFilter
46+
* @param \Magento\PageBuilder\Model\Stage\HtmlFilter $htmlFilter
4747
*/
4848
public function __construct(
4949
\Magento\Cms\Model\ResourceModel\Block\CollectionFactory $blockCollectionFactory,
5050
WidgetDirective $widgetDirectiveRenderer,
5151
LoggerInterface $loggerInterface,
52-
\Magento\PageBuilder\Model\Stage\ScriptFilter $scriptFilter
52+
\Magento\PageBuilder\Model\Stage\HtmlFilter $htmlFilter
5353
) {
5454
$this->blockCollectionFactory = $blockCollectionFactory;
5555
$this->widgetDirectiveRenderer = $widgetDirectiveRenderer;
5656
$this->loggerInterface = $loggerInterface;
57-
$this->scriptFilter = $scriptFilter;
57+
$this->htmlFilter = $htmlFilter;
5858
}
5959

6060
/**
@@ -96,7 +96,7 @@ public function render(array $params): array
9696

9797
if ($block->isActive()) {
9898
$directiveResult = $this->widgetDirectiveRenderer->render($params);
99-
$result['content'] = $this->scriptFilter->removeScriptTags($directiveResult['content']);
99+
$result['content'] = $this->htmlFilter->filterHtml($directiveResult['content']);
100100
} else {
101101
$result['error'] = __('Block disabled');
102102
}

0 commit comments

Comments
 (0)