Skip to content

Commit a25991c

Browse files
author
ogorkun
committed
MC-34385: Filter fields allowing HTML
1 parent f7dfa4c commit a25991c

File tree

3 files changed

+171
-0
lines changed

3 files changed

+171
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\PageBuilder\Model\Validator;
10+
11+
use Magento\Framework\Validator\HTML\TagValidatorInterface;
12+
use Magento\Framework\Validator\HTML\WYSIWYGValidatorInterface;
13+
14+
/**
15+
* Validates HTML elements.
16+
*/
17+
class InnerHtmlValidator implements TagValidatorInterface
18+
{
19+
private const HTML_TYPE_ATTRIBUTE = 'data-content-type';
20+
21+
/**
22+
* @inheritDoc
23+
*/
24+
public function validate(
25+
string $tag,
26+
array $attributes,
27+
string $value,
28+
WYSIWYGValidatorInterface $recursiveValidator
29+
): void {
30+
if (!array_key_exists(self::HTML_TYPE_ATTRIBUTE, $attributes)
31+
|| strtolower($attributes[self::HTML_TYPE_ATTRIBUTE]) !== 'html'
32+
) {
33+
return;
34+
}
35+
36+
$recursiveValidator->validate(html_entity_decode($value));
37+
}
38+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\PageBuilder\Model\Validator;
10+
11+
use Magento\Framework\Validation\ValidationException;
12+
use Magento\Framework\Validator\HTML\AttributeValidatorInterface;
13+
14+
/**
15+
* Validates "src" of iframes.
16+
*/
17+
class SrcAttributeValidator implements AttributeValidatorInterface
18+
{
19+
/**
20+
* @var string[]
21+
*/
22+
private $allowedHosts;
23+
24+
/**
25+
* @param string[] $allowedHosts
26+
*/
27+
public function __construct(array $allowedHosts)
28+
{
29+
$this->allowedHosts = $allowedHosts;
30+
}
31+
32+
public function validate(string $tag, string $attributeName, string $value): void
33+
{
34+
if ($tag !== 'iframe' || $attributeName !== 'src') {
35+
return;
36+
}
37+
38+
if (mb_strpos($value, 'http') !== 0) {
39+
return;
40+
}
41+
$srcHost = parse_url($value, PHP_URL_HOST);
42+
if ($srcHost && $this->allowedHosts) {
43+
$srcHostLength = mb_strlen($srcHost);
44+
$allowed = false;
45+
foreach ($this->allowedHosts as $host) {
46+
$hostLength = mb_strlen($host);
47+
$foundIndex = mb_strpos($srcHost, $host);
48+
if ($foundIndex !== false && ($foundIndex + $hostLength) === $srcHostLength) {
49+
$allowed = true;
50+
break;
51+
}
52+
}
53+
if ($allowed) {
54+
return;
55+
}
56+
}
57+
58+
throw new ValidationException(__('Invalid IFRAME source provided'));
59+
}
60+
}

app/code/Magento/PageBuilder/etc/di.xml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,4 +338,77 @@
338338
<argument name="instanceName" xsi:type="string">Magento\PageBuilder\Model\Dom\HtmlDocument</argument>
339339
</arguments>
340340
</virtualType>
341+
<type name="Magento\PageBuilder\Model\Validator\SrcAttributeValidator">
342+
<arguments>
343+
<argument name="allowedHosts" xsi:type="array">
344+
<item name="youtube" xsi:type="string">youtube.com</item>
345+
<item name="vimeo" xsi:type="string">vimeo.com</item>
346+
</argument>
347+
</arguments>
348+
</type>
349+
<virtualType name="DefaultWYSIWYGValidator">
350+
<arguments>
351+
<argument name="allowedTags" xsi:type="array">
352+
<item name="iframe" xsi:type="string">iframe</item>
353+
</argument>
354+
<argument name="allowedAttributes" xsi:type="array">
355+
<item name="data-content-type" xsi:type="string">data-content-type</item>
356+
<item name="data-appearance" xsi:type="string">data-appearance</item>
357+
<item name="data-element" xsi:type="string">data-element</item>
358+
<item name="data-enable-parallax" xsi:type="string">data-enable-parallax</item>
359+
<item name="data-parallax-speed" xsi:type="string">data-parallax-speed</item>
360+
<item name="data-background-images" xsi:type="string">data-background-images</item>
361+
<item name="data-background-type" xsi:type="string">data-background-type</item>
362+
<item name="data-video-loop" xsi:type="string">data-video-loop</item>
363+
<item name="data-video-play-only-visible" xsi:type="string">data-video-play-only-visible</item>
364+
<item name="data-video-lazy-load" xsi:type="string">data-video-lazy-load</item>
365+
<item name="data-video-fallback-src" xsi:type="string">data-video-fallback-src</item>
366+
<item name="style" xsi:type="string">style</item>
367+
<item name="class" xsi:type="string">class</item>
368+
<item name="data-grid-size" xsi:type="string">data-grid-size</item>
369+
<item name="data-active-tab" xsi:type="string">data-active-tab</item>
370+
<item name="role" xsi:type="string">role</item>
371+
<item name="href" xsi:type="string">href</item>
372+
<item name="data-tab-name" xsi:type="string">data-tab-name</item>
373+
<item name="id" xsi:type="string">id</item>
374+
<item name="data-same-width" xsi:type="string">data-same-width</item>
375+
<item name="target" xsi:type="string">target</item>
376+
<item name="data-link-type" xsi:type="string">data-link-type</item>
377+
<item name="alt" xsi:type="string">alt</item>
378+
<item name="title" xsi:type="string">title</item>
379+
<item name="data-show-button" xsi:type="string">data-show-button</item>
380+
<item name="data-show-overlay" xsi:type="string">data-show-overlay</item>
381+
<item name="data-overlay-color" xsi:type="string">data-overlay-color</item>
382+
<item name="data-autoplay" xsi:type="string">data-autoplay</item>
383+
<item name="data-autoplay-speed" xsi:type="string">data-autoplay-speed</item>
384+
<item name="data-fade" xsi:type="string">data-fade</item>
385+
<item name="data-infinite-loop" xsi:type="string">data-infinite-loop</item>
386+
<item name="data-show-arrows" xsi:type="string">data-show-arrows</item>
387+
<item name="data-show-dots" xsi:type="string">data-show-dots</item>
388+
<item name="data-slide-name" xsi:type="string">data-slide-name</item>
389+
<item name="data-show-controls" xsi:type="string">data-show-controls</item>
390+
<item name="data-locations" xsi:type="string">data-locations</item>
391+
</argument>
392+
<argument name="attributesAllowedByTags" xsi:type="array">
393+
<item name="a" xsi:type="array">
394+
<item name="target" xsi:type="string">target</item>
395+
</item>
396+
<item name="iframe" xsi:type="array">
397+
<item name="src" xsi:type="string">src</item>
398+
<item name="frameborder" xsi:type="string">frameborder</item>
399+
<item name="allowfullscreen" xsi:type="string">allowfullscreen</item>
400+
</item>
401+
</argument>
402+
<argument name="attributeValidators" xsi:type="array">
403+
<item name="src" xsi:type="array">
404+
<item name="iframe-src" xsi:type="object">Magento\PageBuilder\Model\Validator\SrcAttributeValidator</item>
405+
</item>
406+
</argument>
407+
<argument name="tagValidators" xsi:type="array">
408+
<item name="div" xsi:type="array">
409+
<item name="html" xsi:type="object">Magento\PageBuilder\Model\Validator\InnerHtmlValidator</item>
410+
</item>
411+
</argument>
412+
</arguments>
413+
</virtualType>
341414
</config>

0 commit comments

Comments
 (0)