2013-08-04 3 views
0

У меня есть форма комментариев, которая в настоящее время является открытым текстом. Это приятно и легко, потому что я могу просто скрыть все, что смутно напоминает HTML, используя strip_tags и htmlspecialchars.Защита редактора wysiwyg - это HTMLPurifier - единственный способ пойти?

Однако, есть планы превратить это в HTML-форму с поддержкой нескольких тегов <a><b><p><h3> ... и т. Д.

Проблема, которую я вижу, заключается в том, что даже strip_tag'ing ввода и сохранение этих тегов все равно оставит меня открытым для XSS и jscript внутри тегов.

Я знаю, что HTML Purifier можно использовать, чтобы исправить это, но он выглядит действительно громоздким, медленным, и мне трудно поверить, что нет лучшего способа?

Я подумал об использовании редактора BBCode вместо этого, но если предположить, что эти вставки кода в базу данных, как BB, как бы я затем преобразовать его из BB обратно в HTML, чтобы отобразить его?

+0

Почему не какой-то простой BBcode анализатор? – MightyPork

+0

Что случилось с очистителем HTML? Скорость вряд ли будет реальной проблемой. И это громоздко, потому что, ну, дезинфекция HTML-кода сложная. –

ответ

1

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

Во-первых, посмотрите, что произойдет, если вы не используете рекурсию.

BADWORD: CopyThis

CopyCopyThisThis 

который оставляет вас с

CopyThis 

Плохое слово ...

+0

Что это значит для дезинфекции тегов в коде страницы? – MightyPork

+0

Это должно было выделить некоторые типичных проблем, которые многие не учитывают при дезинфекции или снятии тегов/атрибутов/и т. д. –

1

BBCode действительно очень легкое и полезное решение для вашей проблемы.

Я использую MarkItUp! editor, но вы можете найти много других.

Как бы я тогда преобразовал его из BB в HTML, чтобы отобразить его?

Ответ прост: для этого вы можете использовать preg_replace.

Я реализовал это некоторое время назад, поэтому я могу позволить вам использовать мой код синтаксического анализа. Он переводит основные теги, а также некоторые пользовательские, такие как [center]. Очень легко добавить свои собственные теги или заменить текущие.

Сценарий состоит из огромного массива с регулярными выражениями и заменами и одного вызова preg_replace.

function replaceBBcode($str) { 
    $replace = array(

     // inline text formats 
     '/\[b\](.*?)\[\/b\]/is'       => '<b>$1</b>', 
     '/\[i\](.*?)\[\/i\]/is'       => '<i>$1</i>', 
     '/\[u\](.*?)\[\/u\]/is'       => '<u>$1</u>', 
     '/\[s\](.*?)\[\/s\]/is'       => '<s>$1</s>', 
     '/\[sup\](.*?)\[\/sup\]/is'      => '<sup>$1</sup>', 
     '/\[sub\](.*?)\[\/sub\]/is'      => '<sub>$1</sub>', 

     // headings 
     '/\[h1\](.*?)\[\/h1\]/is'      => '<h1>$1</h1>', 
     '/\[h2\](.*?)\[\/h2\]/is'      => '<h2>$1</h2>', 
     '/\[h3\](.*?)\[\/h3\]/is'      => '<h3>$1</h3>', 
     '/\[h4\](.*?)\[\/h4\]/is'      => '<h4>$1</h4>', 
     '/\[h5\](.*?)\[\/h5\]/is'      => '<h5>$1</h5>', 

     // formatting tags 
     '/\[(?:hr|line)\]/is'       => '<hr />', 
     '/\[br\/?\]/is'         => '<br />', 

     // links 
     '/\[url=([^\]]+)\](.*?)\[\/url\]/is'   => '<a href="$1">$2</a>', 
     '/\[link=([^\]]+)\](.*?)\[\/link\]/is'   => '<a href="$1">$2</a>', 
     '/\[url\](.*?)\[\/url\]/is'      => '<a href="$1" title="$1">$1</a>', 
     '/\[link\](.*?)\[\/link\]/is'     => '<a href="$1" title="$1">$1</a>', 

     '/\[img=([^\]]+)\]/is'       => '<img src="$1" alt="" />', 

     // text blocks and block formats 
     '/\[font=([^\]]+)\](.*?)\[\/font\]/is'   => '<span style="font-family: $1;">$2</span>', 
     '/\[size=([0-9]+)\](.*?)\[\/size\]/is'   => '<span style="font-size: $1pt;">$2</span>', 
     '/\[color=([^\]]+)\](.*?)\[\/color\]/is'  => '<span style="color: $1;">$2</span>', 
     '/\[bgcolor=([^\]]+)\](.*?)\[\/bgcolor\]/is' => '<span style="background-color: $1;">$2</span>', 
     '/\[p\](.*?)\[\/p\]/is'       => '<p>$1</p>', 

     // alignment blocks 
     '/\[align=(left|center|right|justify)\](.*?)\[\/align\]/is'  => '<div style="text-align: $1;">$2</div>', 
     '/\[center\](.*?)\[\/center\]/is'    => '<div style="text-align: center;">$1</div>', 
     '/\[left\](.*?)\[\/left\]/is'     => '<div style="text-align: left;">$1</div>', 
     '/\[right\](.*?)\[\/right\]/is'     => '<div style="text-align: right;">$1</div>', 
     '/\[justify\](.*?)\[\/justify\]/is'    => '<div style="text-align: justify;">$1</div>', 

     // lists 
     '/\[list=(disc|circle|square)\](.*?)\[\/list\]/is' => '<ul style="list-style-type:$1;">$2</ul>', 
     '/\[list\](.*?)\[\/list\]/is'     => '<ul>$1</ul>', 
     '/\[list=a\](.*?)\[\/list\]/s'     => '<ol style="list-style-type:lower-alpha;">$1</ol>', 
     '/\[LIST=a\](.*?)\[\/LIST\]/s'     => '<ol style="list-style-type:lower-alpha;">$1</ol>', 
     '/\[list=A\](.*?)\[\/list\]/s'     => '<ol style="list-style-type:upper-alpha;">$1</ol>', 
     '/\[LIST=A\](.*?)\[\/LIST\]/s'     => '<ol style="list-style-type:upper-alpha;">$1</ol>', 
     '/\[list=1\](.*?)\[\/list\]/is'     => '<ol style="list-style-type:decimal;">$1</ol>', 
     '/\[list=I\](.*?)\[\/list\]/is'     => '<ol style="list-style-type:upper-roman;">$1</ol>', 
     '/\[\*\]/is'         => '<li>', 

     // videos 
     '/\[(?:youtube|video|media|movie){1}\](?:https?\:\/\/)?(?:www\.)?(?:youtube\.com\/watch\?v=|youtube\.com\/v\/|youtu\.be\/)?([a-z0-9\-\_]+)\[\/(?:youtube|video|media|movie){1}\]/is' 
        => '<iframe width="560" height="315" src="http://www.youtube.com/embed/$1?wmode=opaque" frameborder="0" allowfullscreen></iframe>', 
    ); 

    // do the tags 
    $str = preg_replace (array_keys($replace), array_values($replace), $str); 

    return $str; 
} 

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

$str = "... text to process ..."; 

// remove unwanted tags 
$str = strip_tags($str); 

// make entities of special chars (not quotes) 
$str = htmlentities($str, ENT_NOQUOTES, $encoding = 'UTF-8'); 

$str_old=""; 

do { 
    $str_old=$str; 
    $str=replaceBBcode($str); 
} while ($str_old != $str); 

// now $str contains the final html tags 
+0

Это безопасно для уязвимостей XSS, хотя это основная проблема OPs? Я не выгляжу так. –

+0

Что делать, если я сделал [правое] [\/right \]'? –

+0

Конечно, вы должны сначала отправить вход через strip_tags, прежде чем даже сохранить его в базу данных. Этот код является только частью рендеринга. – MightyPork

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

  • Нет связанных вопросов^_^