Как предотвратить атаки XSS и запретить определенные теги в HTML, генерируемые синтаксическим анализатором PHP Markdown

Markdown использует очень удобный для пользователя синтаксис форматирования, чтобы выполнить то же самое, что и HTML или Rich Text Formatting, и процесс синтаксического анализа на стороне сервера тоже довольно прост при использовании правильных инструментов. Однако, если вы не будете правильно обрабатывать сгенерированный HTML вашим любимым анализатором Markdown, у вас будут проблемы, если кто-то обнаружит, что ваше приложение уязвимо для атаки XSS. Атаки XSS означают атаку с внедрением кода, когда злоумышленник может выполнить вредоносные сценарии на веб-сайте или в веб-приложении. Дело в том, что уязвимость XSS может быть использована только в том случае, если полезная нагрузка (вредоносный скрипт), который вставляет злоумышленник, будет проанализирована как HTML в браузере жертвы.

Конечно, вы слышали о функциях PHP htmlentities, htmlspecialchars и т.д., функции, которые позволяют вам кодировать и декодировать символы, используемые в HTML, но слишком сложно работать с ним самостоятельно, если у вас мало времени. В основном, ваш синтаксический анализатор должен предоставлять правильные функциональные возможности, однако они также должны быть гибкими и полезными, но иногда из-за особенностей вашего проекта он может работать некорректно на 100%. Например, следующая уценка:

# Hello World
I am a programmer and i wrant to write code. I don't write code with bad intentions, just share my knowledge
```html
alert("First alert");
```
alert("second alert");

Разобрать в HTML с помощью анализатор уценки от cebeb и отображается в браузере, будет только предупреждать «второе предупреждение». Это потому, что синтаксический анализатор достаточно умен, чтобы автоматически конвертировать весь контент внутри блока кода в соответствующие ему объекты HTML. тем не мение тег script вне любого блока кода, все еще интерпретируемый браузером как JavaScript что, очевидно, является проблемой, и IMG, загруженный из несуществующего файла, также будет запущен.

В этой статье мы покажем вам, как предотвратить вставку из JavaScript

Решение с Parsedown

Parsedown делает вещи действительно легкими для вас, избегая разметки внутри уценки, которую вы предоставляете для анализа. Однако он не включен по умолчанию, и этого недостаточно, чтобы предотвратить все способы XSS-атак. По этой причине мы рекомендуем вам, если вы хотите использовать безопасную версию Parsedown, использовать пакет secureparsedown. Изменения, сделанные Эйдан Вудс В исходной библиотеке синтаксического анализа предусмотрена реализация безопасного режима, который защитит HTML от уязвимости для XSS.

В этом случае версия 1.7.0 с изменениями Aidan не была опубликована, поэтому до даты вы можете скачать защищенную версию parsedown из следующего пакета:

composer require aidantwoods/secureparsedown

Преимущество использования этой версии заключается в том, что она будет использовать последнюю версию Parsedown, но также создает безопасный режим. Или, если хотите, измените вручную composer.json файл, а затем запустить composer install:

{
"require": {
"aidantwoods/secureparsedown": "^1.0"
}
}

После установки используйте Parsedown, как обычно, и не забудьте использовать setMarkupEscaped а также setSafeMode методы для предоставления безопасного HTML для отображения:

setSafeMode(true);
// Secure HTML
echo $Parsedown->text($markdown);

Это удобно, потому что весь текст внутри Markdown, интерпретируемый как HTML, будет преобразован в его безобидное представление сущности html (которое предотвращает атаки XSS). Однако эта функция доступна только в этой библиотеке. Если вы хотите предотвратить появление определенных тегов, пожалуйста, внедрите решение и в других библиотеках синтаксических анализаторов.

Решение с другими библиотеками парсеров

Если вы используете другой синтаксический анализатор Markdown в PHP, то он, вероятно, не будет иметь такую ​​же функцию Parsedown. В этом случае вам нужно будет установить библиотеку htmlpurifier. HTML Purifier — это стандартная библиотека HTML-фильтров, написанная на PHP. HTML Purifier не только удалит весь вредоносный код (более известный как XSS) с тщательно проверенным, безопасным, но разрешающим белым списком, но также обеспечит соответствие ваших документов стандартам, чего можно достичь только при полном знании спецификаций W3C.

Чтобы установить htmlpurifier в свой проект с помощью Composer, выполните следующую команду на своем терминале:

composer require "ezyang/htmlpurifier":"dev-master"

После того, как библиотека будет установлена ​​в вашем проекте с помощью composer, вы сможете легко ее использовать. Самый простой способ достичь своей цели — удалить теги скрипта из HTML-кода, созданного на основе уценки, обработанной вашим синтаксическим анализатором, — это запретить использование определенных тегов с параметром HTML.ForbiddenElements (где каждый тег является элементом массива аргументов):

parse($markdown);
// Initialize a config object of html purifier
$config = HTMLPurifier_Config::createDefault();
// The HTML nodes that you want to prevent from being rendered
// as second argument within an array
$config->set('HTML.ForbiddenElements', array('script','applet'));
// Initialize html purifier
$purifier = new HTMLPurifier($config);
// Purify the generated HTML and
// Use this safe HTML to display in the browser !
$HTMLWithoutForbiddenTags = $purifier->purify($parsedMarkdown);

В качестве альтернативы, если вы хотите получить полный контроль над отображаемыми тегами, вы можете решить, какие теги HTML можно отображать и какие атрибуты:

set('Core.LexerImpl', 'DirectLex');
// Define manually which elements can be rendered
// In this example, we allow (almost) all the basic elements that are converted with markdown
$config->set('HTML.Allowed', 'h1,h2,h3,h4,h5,h6,br,b,i,strong,em,a,pre,code,img,tt,div,ins,del,sup,sub,p,ol,ul,table,thead,tbody,tfoot,blockquote,dl,dt,dd,kbd,q,samp,var,hr,li,tr,td,th,s,strike');
// The attributes are up to you
$config->set('HTML.AllowedAttributes', 'img.src,*.style,*.class, code.class,a.href,*.target');
// Create an instance of the purifier with the configuration
$purifier = new \HTMLPurifier($config);
// Print the purified HTML
echo $purifier->purify($parser->text($markdown));
Ссылка на основную публикацию
Adblock
detector