HTML Purifier - iframe и скрипты - PullRequest
       59

HTML Purifier - iframe и скрипты

0 голосов
/ 13 марта 2019

Я использую Очиститель HTML в моем проекте.

Мой html примерно такой. (содержит простой HTML-элемент + скрипт + iframe)

<p>content...<p>
<iframe></iframe>
<script>alert('abc');</script>
<p>content2</p>

С настройкой по умолчанию она превратилась в

<p>content...</p>
<p></p>
<p>Content2</p>

Но если я настрою конфиг следующим образом ...

$config->set('HTML.Trusted', true);
$config->set('HTML.SafeIframe', true);

Я получил это

<p>content...</p>
<p>
    <iframe></iframe>
    <script type="text/javascript"><!--//--><![CDATA[//><!--
    alert('abc');
    //--><!]]></script>
</p>
<p>content2</p>

Есть ли какой-либо способ использовать очиститель HTML, чтобы полностью удалить тег 'script', но сохранить тег 'iframe'? Или другая альтернатива очистителю HTML?

Я пробовал

$config->set('Filter.YouTube', true);
$config->set('URI.SafeIframeRegexp', '%^https://(www.youtube.com/embed/|player.vimeo.com/video/)%');

Но оказалось, что тег 'script' все еще там.

[редактировать]

полный пример.

$config = HTMLPurifier_Config::createDefault();

$html = "<p>content...<p><iframe ...></iframe><script>alert('abc');</script><p>content2</p>";

$config->set(
        'HTML.ForbiddenElements',
        'script'
    );

$purifier = new HTMLPurifier($config);

$clean_html = $purifier->purify($html);

Результат

<p>content...</p><p></p><p>content2</p>

Ответы [ 2 ]

1 голос
/ 13 марта 2019

Вы были наполовину на правильном пути. Если вы установите HTML.SafeIframe на true и URI.SafeIframeRegexp на URL-адреса, которые вы хотите принять (%^https://(www.youtube.com/embed/|player.vimeo.com/video/)% отлично работает), пример ввода:

<p>content...<p>
<iframe src="https://www.youtube.com/embed/blep"></iframe>
<script>alert('abc');</script>
<p>content2</p>

... превращается в ...

<p>content...</p><p>
<iframe src="https://www.youtube.com/embed/blep"></iframe>

</p><p>content2</p>

Объяснение : HTML.SafeIframe допускает тег <iframe>, но HTML-очиститель по-прежнему ожидает белый список для URL-адресов, которые может содержать iframe, так как в противном случае <iframe> открывает слишком большой вредоносный потенциал. URI.SafeIframeRegexp предоставляет белый список (в форме регулярного выражения, которое необходимо сопоставить).

Посмотрите, работает ли это для вас!

код

Это код, который сделал преобразование, которое я только что упомянул:

$dirty = '<p>content...<p>
<iframe src="https://www.youtube.com/embed/blep"></iframe>
<script>alert(\'abc\');</script>
<p>content2</p>';

$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.SafeIframe', true);
$config->set('URI.SafeIframeRegexp', '%^https://(www.youtube.com/embed/|player.vimeo.com/video/)%');

$purifier = new HTMLPurifier($config);

$clean = $purifier->purify($dirty);

Относительно HTML. Надежно

Я умоляю вас никогда не устанавливать HTML.Trusted на true, если вы не полностью доверяете всем и каждому из людей, отправляющих HTML.

Помимо прочего, он позволяет формам во входном HTML-коде пережить безупречную очистку, что (если вы очищаете для веб-сайта, которым, как я полагаю, вы являетесь) делает фишинговые атаки тривиальными. Это позволяет вашему вводу использовать теги стиля, которые остаются невредимыми. Есть некоторые вещи, которые он по-прежнему удаляет (любой HTML-тег, о котором HTML Purifier фактически ничего не знает, т.е. большинство HTML5-тегов являются некоторыми из них, также различными обработчиками атрибутов JavaScript), но есть достаточно векторов атаки, которые вы могли бы не стоит очищаться, если вы используете эту директиву. Как однажды сказал Ambush Commander :

Вы не должны использовать% HTML.Trusted в любом случае; это действительно должно быть названо% HTML.Unsafe или что-то.

0 голосов
/ 14 марта 2019

Рассмотрите возможность использования полноценного HTML-парсера, такого как Masterminds html5-php .Затем HTML-код будет проанализирован без нежелательных изменений, таких как перенос IFRAME в P, и вы сможете манипулировать результирующим DOM-деревом так, как вам нужно, включая удаление некоторых элементов при сохранении других.

Например, следующий код может быть использован для удаления SCRIPT элементов из документа:

foreach ($dom->getElementsByTagName('script') as $script) {
    $script->parentNode->removeChild($script);
}

И обратите внимание, что такой код:

<script type="text/javascript"><!--//--><![CDATA[//><!--
    alert('abc');
//--><!]]></script>`

устарел.Современный эквивалентный HTML5-код:

<script>alert('abc');</script>

точно так же, как в исходном коде перед обработкой в ​​HTML-очистителе.

...