Я хочу разрешить многим пользователям, представленным html для профилей пользователей, в настоящее время пытаюсь отфильтровать то, чего я не хочу, но теперь я хочу изменить и использовать белый список.
Вот мой текущий не-белый список
function FilterHTML($string) { if (get_magic_quotes_gpc()) { $string = stripslashes($string); } $string = html_entity_decode($string, ENT_QUOTES, "ISO-8859-1"); // convert decimal $string = preg_replace('/&#(\d+)/me', "chr(\\1)", $string); // decimal notation // convert hex $string = preg_replace('/&#x([a-f0-9]+)/mei', "chr(0x\\1)", $string); // hex notation //$string = html_entity_decode($string, ENT_COMPAT, "UTF-8"); $string = preg_replace('#(&\#*\w+)[\x00-\x20]+;#U', "$1;", $string); $string = preg_replace('#(<[^>]+[\s\r\n\"\'])(on|xmlns)[^>]*>#iU', "$1>", $string); //$string = preg_replace('#(&\#x*)([0-9A-F]+);*#iu', "$1$2;", $string); //bad line $string = preg_replace('#/*\*()[^>]*\*/#i', "", $string); // REMOVE /**/ $string = preg_replace('#([az]*)[\x00-\x20]*([\`\'\"]*)[\\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iU', '...', $string); //JAVASCRIPT $string = preg_replace('#([az]*)([\'\"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iU', '...', $string); //VBSCRIPT $string = preg_replace('#([az]*)[\x00-\x20]*([\\\]*)[\\x00-\x20]*@([\\\]*)[\x00-\x20]*i([\\\]*)[\x00-\x20]*m([\\\]*)[\x00-\x20]*p([\\\]*)[\x00-\x20]*o([\\\]*)[\x00-\x20]*r([\\\]*)[\x00-\x20]*t#iU', '...', $string); //@IMPORT $string = preg_replace('#([az]*)[\x00-\x20]*e[\x00-\x20]*x[\x00-\x20]*p[\x00-\x20]*r[\x00-\x20]*e[\x00-\x20]*s[\x00-\x20]*s[\x00-\x20]*i[\x00-\x20]*o[\x00-\x20]*n#iU', '...', $string); //EXPRESSION $string = preg_replace('#</*\w+:\w[^>]*>#i', "", $string); $string = preg_replace('#</?t(able|r|d)(\s[^>]*)?>#i', '', $string); // strip out tables $string = preg_replace('/(potspace|pot space|rateuser|marquee)/i', '...', $string); // filter some words //$string = str_replace('left:0px; top: 0px;','',$string); do { $oldstring = $string; //bgsound| $string = preg_replace('#</*(applet|meta|xml|blink|link|script|iframe|frame|frameset|ilayer|layer|title|base|body|xml|AllowScriptAccess|big)[^>]*>#i', "...", $string); } while ($oldstring != $string); return addslashes($string); }
Вышеупомянутое работает очень хорошо, у меня никогда не было проблем после 2 лет использования с ним, но для подхода с белым списком есть что-то похожее на метод stackoverflows C #, но на PHP? http://refactormycode.com/codes/333-sanitize-html
HTML Purifier – это стандартная библиотека фильтров HTML, написанная на PHP. HTML-очиститель не только удалит весь вредоносный код (более известный как XSS) с тщательно проверенным, безопасным, но и разрешенным «белым списком», он также гарантирует, что ваши документы совместимы со стандартами, что только достижимо с полным знанием спецификаций W3C.
Возможно, безопаснее использовать DOMDocument для его правильного анализа, удалить запрещенные теги с помощью removeChild (), а затем получить результат. Не всегда безопасно фильтровать материал с помощью регулярных выражений, особенно если вещи начинают приобретать такую сложность. Хакеры могут найти способ обмануть ваши фильтры, форумы и социальные сети.
Например, браузеры игнорируют пробелы после <. Ваш регулярный фильтр <script, но если я использую <script … большой FAIL!
HTML-очиститель – лучший анализатор / очиститель HTML.
Для тех из вас, которые предлагают просто использовать strip_tags … помните: strip_tags не будет вырезать атрибуты тегов, а сломанные теги также испортят его.
На странице руководства:
Предупреждение. Поскольку strip_tags () фактически не проверяет HTML, частичные или сломанные теги, это может привести к удалению большего количества текста / данных, чем ожидалось.
Предупреждение. Эта функция не изменяет никаких атрибутов в тегах, которые вы разрешаете использовать allowable_tags, включая атрибуты стиля и onmouseover, которые злоумышленник может злоупотреблять при публикации текста, который будет показан другим пользователям.
Вы НЕ МОЖЕТЕ полагаться только на это решение.
Это довольно простая цель – фактически вам нужно проверить что-либо, что НЕ является тегом из списка белых списков и удалять их из источника. Это можно сделать довольно легко с одним регулярным выражением.
function sanitize($html) { $whitelist = array( 'b', 'i', 'u', 'strong', 'em', 'a' ); return preg_replace("/<(^".implode("|", $whitelist).")(.*)>(.*)<\/(^".implode("|", $whitelist).")>/", "", $html); }
Я не проверял это, и там, вероятно, есть ошибка где-то, но вы понимаете, как это работает. Вы также можете посмотреть на язык форматирования, например Textile или Markdown.
Джейми
Вы можете просто использовать функцию strip_tags ()
Поскольку функция определена как
string strip_tags ( string $str [, string $allowable_tags ] )
Вы можете сделать это:
$html = $_POST['content']; $html = strip_tags($html, '<b><a><i><u><span>');
Но обратите внимание, что с помощью strip_tags вы не сможете отфильтровать атрибуты. например
<a href="javascript:alert('haha caught cha!');">link</a>
Попробуйте эту функцию «getCleanHTML» ниже, извлеките текстовый контент из элементов с исключениями элементов с именем тега в белом списке. Этот код чист и прост для понимания и отладки.
<?php $TagWhiteList = array( 'b', 'i', 'u', 'strong', 'em', 'a', 'img' ); function getHTMLCode($Node) { $Document = new DOMDocument(); $Document->appendChild($Document->importNode($Node, true)); return $Document->saveHTML(); } function getCleanHTML($Node, $Text = "") { global $TagWhiteList; $TextName = $Node->tagName; if ($TextName == null) return $Text.$Node->textContent; if (in_array($TextName, $TagWhiteList)) return $Text.getHTMLCode($Node); $Node = $Node->firstChild; if ($Node != null) $Text = getCleanHTML($Node, $Text); while($Node->nextSibling != null) { $Text = getCleanHTML($Node->nextSibling, $Text); $Node = $Node->nextSibling; } return $Text; } $Doc = new DOMDocument(); $Doc->loadHTMLFile("Test.html"); echo getCleanHTML($Doc->documentElement)."\n"; ?>
Надеюсь это поможет.