Очистить вредоносный код, допуская немного HTML (перед сохранением в БД) - PullRequest
0 голосов
/ 12 июня 2019

У меня есть проект Symfony , где любой пользователь может зарегистрировать учетную запись, а затем создать page с формой, содержащей поле content. Я хочу позволить пользователям вставлять некоторые html (такие как жирный текст, нумерованные списки и некоторые другие элементы), что я сделал с помощью WYSIWYG-редактора, CKEditor . Я создал панель инструментов, которая позволяет только выбранным элементам анализироваться в базе данных при сохранении page. Я могу показать содержимое этой страницы, используя:

{{ page.content | raw }}

Это все работает, как и ожидалось. Однако, если бы пользователь должен был скопировать пост-запрос, отредактировать какой-либо JS или другой HTML и использовать cURL для его отправки, это позволило бы им вставить (вредный) код. У меня вопрос: как предотвратить это?

Я читал о «очистке» или «очистке» для очистки ввода пользователя. Что-то вроде HTML Purifier может очистить вывод, что я также рассмотрел, создав своего рода «фильтр ветки белого списка» для элементов, которые я разрешаю. Желательно очистить ввод перед сохранением его в базе данных. Я полагаю, что это распространенная проблема, но я нахожу решения только для того, как очистить вывод, обычно путем экранирования всего HTML, что в моем случае также не является решением, потому что я хочу разрешить некоторый HTML.

Ответы [ 2 ]

3 голосов
/ 12 июня 2019

Вы можете очистить это в своем типе формы после того, как пользователь отправит форму с HTML-очистителем библиотеки и событиями формы symfony:

use HTMLPurifier;
use HTMLPurifier_Config;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;

$builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) {
    $object = $event->getData();

    $config = HTMLPurifier_Config::createDefault();
    $config->set('HTML.AllowedElements', ['a', 'b', 'strong', 'ul', 'li', 'p', 'br']);
    $config->set('Attr.AllowedFrameTargets', ['_blank']);
    $purifier = new HTMLPurifier($config);
    $content = $purifier->purify($object->getContent());

    $object->setContent($content);
});

Так что в этом примере пользовательский контенточищенHTML.AllowedElements определяет, какие элементы не должны быть удалены.После этого объект будет готов к сохранению в вашей базе данных без плохого HTML-контента пользователя.

2 голосов
/ 12 июня 2019

Хитрость не в том, чтобы манипулировать пользовательским вводом. Вам следует проверить / отклонить ввод данных пользователем (пример: пользователь загружает 10 ГБ данных или пользователь запускает элемент div, но не завершает его), но не изменяйте его. Он никуда не денется и не заразит кого-либо, сидя в базе данных.

Когда вы отображаете страницу пользователю, то есть когда вы манипулируете данными. Как вы и сказали, избегайте символов: <для <, & amp для & и & quot для “. </p>

Я недавно программировал для этого, и я использовал XML-парсер (luaexpat). В вашем случае у вас есть PHP с библиотекой парсера XML.

Запустите пользовательский ввод HTML через анализатор XML. Если появляются какие-либо неавторизованные элементы, вы можете либо экранировать их (<) на выходе, либо выдать ошибку вместо содержимого. Также хорошо убедиться, что содержимое имеет допустимый XML, чтобы пользователь не мог испортить оставшуюся часть страницы, не закрывая элемент. </p>

Другая идея - хранить «идентификаторы версий» типов записей. Если вы решите добавить дополнительные функции / атрибуты или переключиться на другую кодировку (например, BBCose), напишите заметку в базу данных, чтобы было легче декодировать записи. Это еще одна причина, по которой вам НЕ следует изменять ввод пользователя, а вывод пользователя, если вы начинаете с запрета изображений, а потом решаете разрешить его.

Также атрибуты белого списка тоже. Не позволяйте кому-либо помещать JavaScript в атрибуты (такие как <div onclick=“MaliciousCode();”>)

Обязательно обратите внимание на атаки с использованием SQL-инъекций и HTML-инъекций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...