2013-02-11 9 views
0

У меня есть система блога, и пользователь должен вводить содержимое в текстовую область html, включая теги html, такие как <p>. Это сохраняется в базе данных. Если этот вход затем эхом передается на веб-страницу с использованием php, как я могу избежать вывода для защиты от XSS, но сохранить значение html-тегов, чтобы сообщение в блоге было отформатировано правильно? Если я использую htmlentities($blog_content), он буквально печатает теги html на странице, поэтому вы видите <p>hello this is a blog</p>.Как я могу безопасно выводить содержимое, содержащее HTML-теги?

Возможно ли это?

+0

Вы протестировали htmlentities()? –

+1

Возможный дубликат [PHP XSS Prevention WhiteListing] (http://stackoverflow.com/questions/2992674/php-xss-prevention-whitelisting) – Quentin

ответ

0

Что вы хотите, это выборочная фильтрация или дезинфекция. Другими словами, вы хотите дать код HTML, но не другие, возможно, вредоносные теги. Это очень сложный бизнес, особенно потому, что синтаксис HTML очень сложный, и чрезмерно простые попытки санировки подвержены ошибкам, которые позволяют вставлять теги через искаженный HTML в любом случае.

Если возможно, вы должны держаться подальше от того, чтобы пользователи могли отправлять HTML-файлы вообще. Используйте специальный язык разметки, такой как разметка Wiki, Markdown, BBcodes или аналогичный.

Если вы уверены, что делаете, вы должны выбрать хорошую, хорошо протестированную, надежную библиотеку, которая обеспечивает такие функции санитизации. HTML Purifier - это единственное, что я знаю, которое соответствует этому описанию.

+0

Лучшее решение. Не решался ответить на это сам, потому что они уже, кажется, принимают HTML, и я не хотел предлагать изменения. Но если можно использовать другой язык разметки - сделайте это. –

+0

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

0

Ну, вы можете просто раздеться <script> теги, используя strip_tags()это не пуленепробиваемый решение, но вы можете улучшить безопасность, просто позволяя некоторые теги (в основном полужирный, курсив, ссылки и несколько больше) ...

Затем вы можете легко распечатать свой контент и избежать выполнения javascript.

$text = '<p>Test paragraph.</p><!-- Comment --> <a href="#fragment">Other text</a>'; 
echo strip_tags($text); 
echo "\n"; 

// Allow <p>, <a> and some formatting 
echo strip_tags($text, '<p><a><i><em><b><strong>'); 
+0

'strip_tags' недостаточно, так как он не удаляет атрибуты из элементов. Рассмотрим '' –

+0

. Какая часть ** это не пуленепробиваемое решение ** вы пропустили? :) – Napolux

+0

Вы упомянули, что вы можете «улучшить безопасность, просто допустив некоторые теги», что на самом деле не так. Вы действительно не улучшаете безопасность, реализуя белый список разрешенных тегов. Вы также упомянули, что можете «избежать выполнения javascript», который вы не можете с помощью этого метода. Только для примечания стороны: нисходящий удар был не от меня. Не расстраивайся. Я просто предлагаю улучшение. –

0

Вы можете использовать strip_tags() и разрешить некоторые HTML-элементы:

echo strip_tags($text, '<p><a>'); 

Однако, это все еще опасно, так как кто-то может вставить код как

<p onclick="doSomething();">...</p> 

Так было бы лучше, если вы должны использовать способ DOMDocumentloadHtml() для загрузки ваших данных из базы данных. Затем вам нужно пройти через узлы и проверить, есть ли какие-либо атрибуты или узлы, которые вы, возможно, должны удалить, например. используя DOMNode::hasAttributes и DOMNode::hasChildNodes.

+0

Правильный ответ - комбинация 'strip_tags' и' DOMDocument'. Единственное, что я имею здесь, это реализовать белый список разрешенных тегов, а не черный список (на всякий случай, если вы что-то пропустили).Важное замечание здесь - НЕ ДОПУСКАТЬ сообщение, если HTML неверен. В противном случае любая логика может сломаться на некорректном HTML. –

Смежные вопросы