Как я могу очистить пользовательский ввод HTML, удалив все возможные сценарии?

Я использую CKEditor, чтобы пользователи могли вводить форматированный текст и даже встроенные изображения. Этот контент отправляется другим пользователям. Как я могу предотвратить любые вредоносные инъекции, такие как XSS? Я думаю, мне просто нужно очистить HTML, удалив все возможные сценарии на стороне сервера, но я не могу найти какой-либо проверенный инструмент для этого. Даже SafeHTMLUtils GWT не будет работать. потому что он слишком сильно изменяет HTML, нарушая пользовательский ввод.

Изменить:

Я нашел дезинфицирующее средство под названием Jsoup. Он делает именно то, что мне нужно. Но даже в расслабленном режиме удаляются теги img со встроенными изображениями.


person Federico Pugnali    schedule 16.03.2014    source источник


Ответы (2)


Мне удалось очистить ввод HTML с помощью Jsoup следующим образом:

Jsoup.clean(dirtyHTML, 
                Whitelist.relaxed()
                .addProtocols("img","src","data")
                .addAttributes(":all", "style")
                .addTags("span")));

Он принимает любой img с содержимым src, начинающимся с «data:». Пока все в порядке, но я задал вопрос чтобы найти способ просто принять сгенерированный CKEditor контент "data:;base64".

Чтобы отобразить продезинфицированные данные HTML принимающему пользователю, мы используем изолированный iframe, чтобы избежать катастроф css (например, изображение с фиксированным положением, покрывающее всю страницу).

<iframe sandbox="allow-same-origin">Sanitized HTML here inside body tag</iframe>
person Federico Pugnali    schedule 17.03.2014

Очень сложно автоматически отделить хороший HTML от плохого. Я бы не стал доверять никакому инструменту, даже если они утверждают, что они безопасны. Такое разделение не будет ограничиваться проверкой того, какие теги или атрибуты используются, и блокировать некоторые, такие как тег скрипта или атрибуты обработчика событий (например, img.onerror). Существует множество методов, которые выигрывают от того, как браузер анализирует/обрабатывает HTML. Каждый день появляются новые методы эксплойта.

Я считаю, что самый безопасный способ — использовать редакторы Markdown, подобные тому, который используется здесь, в Stackoverflow.

Вы можете найти некоторые ссылки здесь: Плагин JQuery/JS Markdown?

person mesutozer    schedule 16.03.2014
comment
Спасибо за информацию. Я читал об использовании PageDown здесь. Но следует отметить, что Markdown небезопасен в том, что касается пользовательского ввода. Практически все допустимо в Markdown, в частности что-то вроде ‹script›doEvil();‹/script›. Этот репозиторий PageDown включает в себя два подключаемых модуля, которые Stack Exchange использует для очистки ввода пользователя; см. описание Markdown.Sanitizer.js ниже. Я думаю, у нас нет другого решения, кроме как довериться какому-нибудь дезинфицирующему средству. - person Federico Pugnali; 17.03.2014
comment
Я думаю, было бы проще использовать Markdown + дезинфицирующее средство, которое полностью удаляет html. В дополнение к удалению (или попытке удаления) HTML-кода из пользовательского ввода, это дезинфицирующее средство может html-кодировать введенные данные, а затем применять правила уценки для добавления некоторого HTML-кода. Таким образом, гарантируется, что даже если пользователь сможет пройти часть этапа удаления, этот html будет закодирован в выводе. - person mesutozer; 17.03.2014
comment
Я не могу полностью удалить HTML в моем случае. Весь смысл функциональности заключается в том, чтобы пользователи могли отправлять готовые HTML-статьи другим пользователям. Я думаю, что я буду в порядке с чем-то вроде jsoup, очищающим только скрипты, но я хотел бы сохранить встроенные изображения. - person Federico Pugnali; 17.03.2014
comment
Я не настаиваю, пожалуйста, не поймите меня неправильно. Я просто хочу внести ясность. Когда используется уценка, html-теги не отображаются в пользовательском вводе. Так работает уценка. В нем есть некоторые соглашения, например, когда слово появляется между двумя звездочками (*), оно должно быть выделено жирным шрифтом. Таким образом, обычно данные уценки, предоставляемые пользователем, не включают HTML. В этот момент Sanitiser может удалить весь HTML-код. Затем он HTML кодирует входную строку. Затем преобразует соглашения об уценке в настоящие HTML-теги (например, преобразование * в ‹b›). - person mesutozer; 17.03.2014
comment
Согласно этому: michelf.ca/blog/2010/markdown-and-xss проблема по-прежнему заключается в очистке HTML - person Federico Pugnali; 17.03.2014