Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Это в свою очередь значит, что удаление потенциально опасных элементов с помощью str_replace, preg_replace (PHP), s/<script/.../i (Perl, sed) и прочих replace() функций для других языков не даст желаемых результатов.
$code = "<h2> Hello! </h2> <h3> My Name</h3> <B>is</b> <\0b>bug</b>"; echo htmlspecialchars(strip_tags($code, "<h2><B>") );
<h2> Hello! </h2> My Name <B>is</b> <b>bug</b>
$code = "<h2> Hello! </h2> <h3> My Name</h3> <B>is</b> <\0b>bug</b>"; echo htmlspecialchars(strip_tags($code, "<h2>") );
<h2> Hello! </h2> My Name is bug
$w = array('& lt;b& gt;', '& lt;/b& gt;', '& lt;p& gt;', '& lt;/p& gt;'); // парсер - лох, пробелы после '&' лишние
$t = array('<b>', '</b>', '<p>', '</p>');
echo str_replace($w, $t, htmlspecialchars($user_html) );
Самый правильный подход, который не допустит подобных дыр в системе фильтрации, это оставлять только то, что явно разрешено, а всё остальное вырезать подчистую.
Главное, как сказал выше Xeon303, нужно в начале запрещать всё и только потом разрешать то что нужно.
$source = '<code>#include <stdio.h></code>';
var_dump(strip_tags($source, '<code>'));
=> string(11) "<code>#include </code>"
$w = array('& lt;code& gt;', '& lt;/code& gt;');
$t = array('<code>', '</code>');
var_dump( str_replace($w, $t, htmlspecialchars($source)));
=> string(39) "<code>#include & lt;stdio.h& gt;</code>"
Нулевой символ внутри тега