[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Запрет на вставку JavaScript через WYSIWYG
niksan
У меня на сайте пользователям предоставляется возможность редактировать свою страничку при помощи WYSIWYG редактора. Как мне сделать запрет на ввод через него Java Script кода? Чтобы html теги при этом так же могли вставляться.



Спустя 1 час, 6 минут (9.06.2010 - 16:43) Kuzya написал(а):
1. Резать тег <script>
2. Заменять фразу "javascript" на "javascript"
3. Заменять фразу "expression" на "expre ssion"
4. Запретить события on*** в атрибутах тегов.
В последнем лучше не делать фильтрацию по готовому списку событий, а вырезать все атрибуты тегов начинающиеся на "on".

Спустя 1 минута, 58 секунд (9.06.2010 - 16:45) vasa_c написал(а):
Ага, и учесть ещё бесчисленное количество вариантов.

Спустя 1 минута, 49 секунд (9.06.2010 - 16:47) Basili4 написал(а):
Цитата (vasa_c @ 9.06.2010 - 17:45)
Ага, и учесть ещё бесчисленное количество вариантов.

Какие еще варианты Kuzya перечислил все. Разве нет ?

Спустя 1 минута, 37 секунд (9.06.2010 - 16:49) Kuzya написал(а):
Цитата
Ага, и учесть ещё бесчисленное количество вариантов.

Я вроде все припомнил. Какие ещё могут быть, по вашему?

Спустя 8 минут, 20 секунд (9.06.2010 - 16:57) vasa_c написал(а):
<scr<script>ipt>
<\0script>

и ещё навалом.

Спустя 2 минуты, 3 секунды (9.06.2010 - 16:59) DedMorozzz написал(а):
если скрипт заменить на " ", то всё. Вложеные теги не закроются

Спустя 1 минута, 12 секунд (9.06.2010 - 17:00) vasa_c написал(а):
<script<script>> ?

Спустя 3 минуты, 6 секунд (9.06.2010 - 17:04) Leningrad00 написал(а):
vasa_c абсолютно прав.
Я бы пошел от обратного: разрешал бы только то, что можно; резать любые теги, кроме перечня заведомо безопасных.

Спустя 1 минута, 8 секунд (9.06.2010 - 17:05) DedMorozzz написал(а):
да и если заменять на '', то по циклу пускать, после каждой итерации смотреть, поменяло ли что нибуть, если нет - то ити дальше, там хоть десятки вложеностей будет...

Спустя 3 минуты, 56 секунд (9.06.2010 - 17:09) vasa_c написал(а):
Я привёл просто один пример. Вы нашли противоядие. Я привёл контрпример, вы опять нашли решение конкретного вопроса. Дальше можно идти до бесконечности.

Чтобы решить абстрактную проблему вырезания JS-кода из произвольного HTML, нужно учесть:
1. Все моменты, когда браузер может посчитать что-то за код, а этих моментов во всех браузерах и их версиях пруд пруди, и даже разработчики часто о них не знают.
2. Учесть все хитрож.е варианты ввода.

Итого - задача в такой постановке слишком геморройная для решения.

Спустя 40 минут, 1 секунда (9.06.2010 - 17:49) Nikitian написал(а):
Использую этот фильтр тэгов и доволен как слон.
strip_tags_smart()

<?php
/**
* Более продвинутый аналог strip_tags() для корректного вырезания тагов из html кода.
* Функция strip_tags(), в зависимости от контекста, может работать не корректно.
* Возможности:
* - корректно обрабатываются вхождения типа "a < b > c"
* - корректно обрабатывается "грязный" html, когда в значениях атрибутов тагов могут встречаться символы < >
* - корректно обрабатывается разбитый html
* - вырезаются комментарии, скрипты, стили, PHP, Perl, ASP код, MS Word таги, CDATA
* - автоматически форматируется текст, если он содержит html код
* - защита от подделок типа: "<
<fake>script>alert('hi')</</fake>script>"
*
*
@param string $s
*
@param array $allowable_tags Массив тагов, которые не будут вырезаны
* Пример: 'b' -- таг останется с атрибутами, '
<b>' -- таг останется без атрибутов
*
@param bool $is_format_spaces Форматировать пробелы и переносы строк?
* Вид текста на выходе (plain) максимально приближеется виду текста в браузере на входе.
* Другими словами, грамотно преобразует text/html в text/plain.
* Текст форматируется только в том случае, если были вырезаны какие-либо таги.
*
@param array $pair_tags массив имён парных тагов, которые будут удалены вместе с содержимым
* см. значения по умолчанию
*
@param array $para_tags массив имён парных тагов, которые будут восприниматься как параграфы (если $is_format_spaces = true)
* см. значения по умолчанию
*
@return string
*
*
@license http://creativecommons.org/licenses/by-sa/3.0/
* @author Nasibullin Rinat, http://orangetie.ru/
* @charset ANSI
*
@version 4.0.14
*/

function strip_tags_smart(
/*string*/ $s,
array $allowable_tags = null,
/*boolean*/ $is_format_spaces = true,
array $pair_tags = array('script', 'style', 'map', 'iframe', 'frameset', 'object', 'applet', 'comment', 'button', 'textarea', 'select'),
array $para_tags = array('p', 'td', 'th', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'form', 'title', 'pre')
)

{
//return strip_tags($s);
static $_callback_type = false;
static $_allowable_tags = array();
static $_para_tags = array();
#regular expression for tag attributes
#correct processes dirty and broken HTML in a singlebyte or multibyte UTF-8 charset!

static $re_attrs_fast_safe = '(?![a-zA-Z\d]) #statement, which follows after a tag
#correct attributes
(?>
[^>"
\']+
| (?<=[\=\x20\r\n\t]|\xc2\xa0) "[^"]*"
| (?<=[\=\x20\r\n\t]|\xc2\xa0)
\'[^\']*\'
)*
#incorrect attributes
[^>]*+'
;

if (is_array($s))
{
if ($_callback_type === 'strip_tags')
{
$tag = strtolower($s[1]);
if ($_allowable_tags)
{
#tag with attributes
if (array_key_exists($tag, $_allowable_tags)) return $s[0];

#tag without attributes
if (array_key_exists('<' . $tag . '>', $_allowable_tags))
{
if (substr($s[0], 0, 2) === '</') return '</' . $tag . '>';
if (substr($s[0], -2) === '/>') return '<' . $tag . ' />';
return '<' . $tag . '>';
}
}

if ($tag === 'br') return "\r\n";
if ($_para_tags && array_key_exists($tag, $_para_tags)) return "\r\n\r\n";
return '';
}
trigger_error('Unknown callback type "' . $_callback_type . '"!', E_USER_ERROR);
}

if (($pos = strpos($s, '<')) === false || strpos($s, '>', $pos) === false) #speed improve
{
#tags are not found
return $s;
}

$length = strlen($s);

#unpaired tags (opening, closing, !DOCTYPE, MS Word namespace)
$re_tags = '~ <[/!]?+
(
[a-zA-Z][a-zA-Z\d]*+
(?>:[a-zA-Z][a-zA-Z\d]*+)?
) #1
'
. $re_attrs_fast_safe . '
>
~sxSX'
;

$patterns = array(
'/<([\?\%]) .*? \\1>/sxSX', #встроенный PHP, Perl, ASP код
'/<\!\[CDATA\[ .*? \]\]>/sxSX', #блоки CDATA
#'/<\!\[ [\x20\r\n\t]* [a-zA-Z] .*? \]>/sxSX', #:DEPRECATED: MS Word таги типа <![if! vml]>...<![endif]>


'/<\!--.*?-->/sSX', #комментарии

#MS Word таги типа "<![if! vml]>...<![endif]>",
#условное выполнение кода для IE типа "<!--[if expression]> HTML <![endif]-->"
#условное выполнение кода для IE типа "<![if expression]> HTML <![endif]>"
#см. http://www.tigir.com/comments.htm

'/ <\! (?:--)?+
\[
(?> [^\]"
\']+ | "[^"]*" | \'[^\']*\' )*
\]
(?:--)?+
>
/sxSX'
,
);

if ($pair_tags)
{
#парные таги вместе с содержимым:
foreach ($pair_tags as $k => $v) $pair_tags[$k] = preg_quote($v, '/');
$patterns[] = '/ <((?i:' . implode('|', $pair_tags) . '))' . $re_attrs_fast_safe . '(?<!\/)>
.*?
<\/(?i:
\\1)' . $re_attrs_fast_safe . '>
/sxSX'
;
}
#d($patterns);

$i = 0; #защита от зацикливания
$max = 99;
while ($i < $max)
{
$s2 = preg_replace($patterns, '', $s);
if (preg_last_error() !== PREG_NO_ERROR)
{
$i = 999;
break;
}

if ($i == 0)
{
$is_html = ($s2 != $s || preg_match($re_tags, $s2));
if (preg_last_error() !== PREG_NO_ERROR)
{
$i = 999;
break;
}
if ($is_html)
{
if ($is_format_spaces)
{
/*
В библиотеке PCRE для PHP \s - это любой пробельный символ, а именно класс символов [\x09\x0a\x0c\x0d\x20\xa0] или, по другому, [\t\n\f\r \xa0]
Если \s используется с модификатором /u, то \s трактуется как [\x09\x0a\x0c\x0d\x20]
Браузер не делает различия между пробельными символами, друг за другом подряд идущие символы воспринимаются как один
*/
#$s2 = str_replace(array("\r", "\n", "\t"), ' ', $s2);
#$s2 = strtr($s2, "\x09\x0a\x0c\x0d", ' ');

$s2 = preg_replace('/ [\x09\x0a\x0c\x0d]++
| <((?i:pre|textarea))'
. $re_attrs_fast_safe . '(?<!\/)>
.+?
<\/(?i:
\\1)' . $re_attrs_fast_safe . '>
\K
/sxSX'
, ' ', $s2);
if (preg_last_error() !== PREG_NO_ERROR)
{
$i = 999;
break;
}
}


#массив тагов, которые не будут вырезаны
if ($allowable_tags) $_allowable_tags = array_flip($allowable_tags);

#парные таги, которые будут восприниматься как параграфы
if ($para_tags) $_para_tags = array_flip($para_tags);
}
}
#if

#tags processing

if ($is_html)
{
$_callback_type = 'strip_tags';
$s2 = preg_replace_callback($re_tags, __FUNCTION__, $s2);
$_callback_type = false;
if (preg_last_error() !== PREG_NO_ERROR)
{
$i = 999;
break;
}
}


if ($s === $s2) break;
$s = $s2; $i++;
}#while
if ($i >= $max) $s = strip_tags($s); #too many cycles for replace...

if ($is_format_spaces && strlen($s) !== $length)
{
#remove a duplicate spaces
$s = preg_replace('/\x20\x20++/sSX', ' ', trim($s));
#remove a spaces before and after new lines
$s = str_replace(array("\r\n\x20", "\x20\r\n"), "\r\n", $s);
#replace 3 and more new lines to 2 new lines
$s = preg_replace('/[\r\n]{3,}+/sSX', "\r\n\r\n", $s);
}
return $s;
}
?>


_____________
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.