Skip to content

Commit 674a172

Browse files
Merge pull request #7 from magento-borg/MC-37989
MC-37989: [Backport for 2.3.x-p1]Filter fields allowing HTML
2 parents 6ec6804 + 1fbfda8 commit 674a172

File tree

3 files changed

+180
-0
lines changed

3 files changed

+180
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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 IframeSrcAttributeValidator implements AttributeValidatorInterface
18+
{
19+
/**
20+
* @var string[]
21+
*/
22+
private $allowedHosts;
23+
24+
/**
25+
* IframeSrcAttributeValidator constructor.
26+
*
27+
* @param string[] $allowedHosts
28+
*/
29+
public function __construct(array $allowedHosts)
30+
{
31+
$this->allowedHosts = $allowedHosts;
32+
}
33+
34+
/**
35+
* @inheritDoc
36+
*/
37+
public function validate(string $tag, string $attributeName, string $value): void
38+
{
39+
if ($tag !== 'iframe' || $attributeName !== 'src') {
40+
return;
41+
}
42+
43+
if (mb_strpos($value, 'http') !== 0) {
44+
//Relative link
45+
return;
46+
}
47+
// phpcs:ignore Magento2.Functions.DiscouragedFunction
48+
$srcHost = parse_url($value, PHP_URL_HOST);
49+
if (!$srcHost || !$this->allowedHosts) {
50+
//Either the link is invalid or we do not have the allowed list.
51+
return;
52+
}
53+
$srcHostLength = mb_strlen($srcHost);
54+
foreach ($this->allowedHosts as $host) {
55+
$hostLength = mb_strlen($host);
56+
$foundIndex = mb_strpos($srcHost, $host);
57+
if ($foundIndex !== false && ($foundIndex + $hostLength) === $srcHostLength) {
58+
return;
59+
}
60+
}
61+
62+
throw new ValidationException(__('Invalid IFRAME source provided'));
63+
}
64+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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+
// phpcs:ignore Magento2.Functions.DiscouragedFunction
37+
$recursiveValidator->validate(html_entity_decode($value));
38+
}
39+
}

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

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

0 commit comments

Comments
 (0)