|
|
|
| Привет!
Застрял я на ситуации которая позволяет посетителям публиковать новости.
К публикации подключен WYSIWYG редактор, делаю фильтр который оставляет только разрешенные теги при помощи strip_tags
<?php
//Текст с тегами
$text='
Текст<br><br style="clear:both;">
<b>123</b>
<strong>123</strong>
<i>123</i>
<del>123</del><br>
<del>123<br></del><br>
<center>123</center>
<h1>123</h1>
<h2>123</h2>
<h3>123</h3>
<ul>
<li>123</li>
</ul>
<ol>
<li>123</li>
</ol>
<a href="123" onclick="..."></a>
';
$text=strip_tags($text, '<a><b><strong><i><del><em><center><h1><h2><li><ol><ul><br>');
echo htmlspecialchars($text);
echo '<br>';
?>
|
прошу подсказки как реализовать вырезку левых атрибутов у тегов?
По сути здесь нужно вырезать все атрибуты кроме как у тега A href="" | |
|
|
|
|
|
|
|
для: tima2010
(17.03.2012 в 16:57)
| | как-то так
<?php
//Текст с тегами
$text='
Текст<br><br style="clear:both;">
<b>123</b>
<strong>123</strong>
<i>123</i>
<del>123</del><br>
<del>123<br></del><br>
<center>123</center>
<h1>123</h1>
<h2>123</h2>
<h3>123</h3>
<ul>
<li>123</li>
</ul>
<ol>
<li>123</li>
</ol>
<a href="123" onclick="..."></a>
';
$text = preg_replace("/(style=\".+?\"|onclick=\".+?\")/","",$text);
echo htmlspecialchars($text);
echo '<br>';
?>
|
если есть другие события помимо onclick, тожно добавить в регулярку | |
|
|
|
|
|
|
|
для: ladan
(19.03.2012 в 01:57)
| | Спасибо! А какие еще могут быть лишние "опасные" атрибуты?
Понятно что нужно учитывать одинарные кавычки тоже.
Получается придется перечислить все javascript события? ...
Сколько же их... можно же написать и так <a href='javascript:alert(123213);'>123</a>
Даже если вырезать javascript из строки то обойти ведь тоже просто javajavascriptscript
Может тогда пойти с того что разрешено? типа вырезать все кроме
$text = preg_replace("/<([a-z][a-z0-9]*)[^>]*?(\/?)>/i",'<$1$2>', $text);
|
видимо придется просто отключить теги... мде | |
|
|
|
|
|
|
|
для: tima2010
(20.03.2012 в 15:46)
| | Что вы пытаетесь сделать? Защититься? Ну так вы уже это сделали. htmlspecialchars() преобразует специальные символы в HTML-сущности и ни один скрипт прописанный пользователем не сработает на вашей странице. Если же вы хотите использовать теги для форматирования, то обычно для этого применяют так называемые bbCode. Т.е. Пользователь пишет теги не в < >, а в [ ], также как и здесь при форматировании сообщения, а скрипт потом все что разрешено заменяет на реальные теги. Соответственно что не разрешено вами лично так и останется в квадратных скобках и никак не будет функционировать. | |
|
|
|
|
|
|
|
для: Sfinks
(20.03.2012 в 20:15)
| | Используется wysiwyg редактор, отформатированный текст сразу отображается без bbcode.
Не хочется заставлять пользователя использовать [ b ] текст [/ b ], аудитория не та
Как известно в wisiwyg редактор можно скопировать ссылку с какого либо сайта и вставить в окно редактора. Все атрибуты которые были в скопированной ссылке сохраняются.
Поэтому думаю как их отрубить.
Либо придется использовать вырезку всех атрибутов и позволить использовать теги у которых атрибуты не обязательны. А ссылку кому надо писать в виде bbcode [ url href='' ] ссылка [/ url ] | |
|
|
|
|
|
|
|
для: tima2010
(20.03.2012 в 21:07)
| | у меня на форуме стоит редактор tinyMCE. Работает как у вас походу и такие же проблемы. Если бы яваскрипт знал, то лучше бы сделал как на этом форуме, через bbcode. Может просто mysql_real_escape_string обрабатывать переменные? Я по началу тоже думал вырезать все лишние атрибуты и теги, но потом понял, что не буду ничего такого делать, а буду сразу банить людей за какие-нибудь пакости :) | |
|
|
|
|
|
|
|
для: ladan
(20.03.2012 в 22:02)
| | Просто пакость может быть незаметной :) И попадут в админ панель.
Пока что остановился на варианте:
<?php
$text = stripslashes($_POST['text']);
$text = strip_tags($text, '<b><strong><i><u><del><strike><em><center><h2><li><ol><ul><br><hr><center>'); // вырезаем все теги кроме...
$text = preg_replace('/<([a-z][a-z0-9]*)[^>]*?(\/?)>/i','<$1$2>', $text); // у всех тегов вырезаем атрибуты
?>
|
| |
|
|
|
|
|
|
|
для: ladan
(20.03.2012 в 22:02)
| | > а буду сразу банить людей за какие-нибудь пакости
Не хотелось бы каркать, но может так случиться, что банить будет просто некого, т.к. БД будет удалена, а вместо сайта будет редирект на какую-нибудь порнуху ) | |
|
|
|
|
|
|
|
для: Sfinks
(20.03.2012 в 23:00)
| | Посмотрите пожалуйста, правильно ли я понимаю данное выражение:
$text = preg_replace("#\[url\][\s]*([\S]+)[\s]*\[\/url\]#isU",'<a href="\\1" target="_blank">\\1</a>',$text);
|
Что конкретно означает этот участок? [\s]*([\S]+)[\s]
то что не должно быть пробелов? Ведь URL по сути не может содержать пробелов, если это так то очень хорошо :) | |
|
|
|
|
|
|
|
для: tima2010
(20.03.2012 в 23:03)
| | Да, верно.
[\s]* - 0 или более пробелов
[\S]+ - 1 или более НЕ пробелов.
только [ ] тут абсолютно не нужны, а [\S]+ я бы заменил на РВ описывающее УРЛ. | |
|
|
|
|
|
|
|
для: tima2010
(20.03.2012 в 23:03)
| | isU - вы этим что хотели сказать? "i", "s" понятно. "U" - вы же не имели ввиду УТФ? ) потому что УТФ обозначается "u". А что значит "U" я не помню и сейчас чет не получается найти. Но однозначно не УТФ. | |
|
|
|
|
|
|
|
для: Sfinks
(20.03.2012 в 23:53)
| | спасибо!
Странно работает и с U и с u | |
|
|
|
|
|
|
|
для: Sfinks
(20.03.2012 в 23:53)
| | Хотел еще поинтересоваться, можно ли как то применить htmlspecialchars к данным которые мы выдергиваем из [ ulr ]http://softtime.ru/forum/pstadd.php?id_forum=6[/ url]
именно к самой ссылке ?
Есть вариант:
<?php
$text = '[ url]http://softtime.ru/forum/pstadd.php?id_forum=6[/ url]';
$url = preg_replace("#\[mp3\][\s]*([\S]+)[\s]*\[\/mp3\]#isU",'\\1',$text);
$url = htmlspecialchars($url);
/* Но теперь на место ссылку не поставить... */
?>
|
но ссылку не выйдет на место поставить.
Получается нужно сделать что то типа:
$url= preg_replace("#\[url\][\s]*([\S]+)[\s]*\[\/url\]#isu",'<a href="htmlspecialchars(\\1)" target="_blank">\\1</a>',$text);
|
Применять htmlspecialchars задумал чтобы избежать заместо ссылок вставки javascript коды к примеру
$text = '[url]"onclick="alert(123);"[/url]';
| и прочей дребедени
а найти толковый валидатор ссылок не получается... | |
|
|
|
|
|
|
|
для: tima2010
(21.03.2012 в 09:00)
| | Это делается через preg_replace_callback() функцию.
Но лучше нате вам толковый валидатор:
<?
$pattern = "#http://([а-яёa-z\d][а-яёa-z\d\-]*\.)+[а-яёa-z]{2,6}(/([а-яё\w\-\.]*[а-яё\w\-/]{1})*(\?(([a-z][\w\-]*)?(=(%[a-z\d]{2}|[\w\-\.\+])*)?)?(&(amp;)?(([a-z][\w\-]*)?(=(%[a-z\d]{2}|[\w\-\.\+])*)?)?)*)?)?#ui";
| берете все что между ## и вставляете вместо [\S]+ | |
|
|
|
|
|
|
|
для: Sfinks
(21.03.2012 в 09:46)
| | Большое спасибо | |
|
|
|
|
|
|
|
для: Sfinks
(20.03.2012 в 23:00)
| | ну тогда почаще бэкапы делать :) | |
|
|
|
|
|
|
|
для: ladan
(21.03.2012 в 11:18)
| | Что то не так с рег. выражением? | |
|
|
|
|
|
|
|
для: tima2010
(21.03.2012 в 11:36)
| | да не, все в норме ) | |
|
|
|
|
|
|
|
для: tima2010
(17.03.2012 в 16:57)
| | Разбейте задачу на подзадачи:
1. Находим все теги.
2. Удаляем не разрешенные теги.
3. Для каждого тега находим все атрибуты
4. Удаляем не разрешенные атрибуты, для не левых - проверяем корректность заполнения, если что-то не так - вырезаем и их.
Обратите внимание - лучше всего по умолчанию запретить все теги/атрибуты, а уже потом разрешить только необходимые - это гораздо проще чем перечислять все теги/атрибуты, которые мы хотим запретить и при этом забыть про пару-другую, через которые в итоге и поломают :)
PS: присмотритесь к функции "preg_replace_callback" | |
|
|
|
|
|
|
|
для: Гость
(21.03.2012 в 10:33)
| | Так почти и получилось:
<?php
/* Вырезаем все теги кроме разрешенных */
$text = strip_tags($text, '<b><strong><i><u><del><strike><em><center><h2><li><ol><ul><br><hr><center>');
/* Вырезаем все атрибуты */
$text = preg_replace('/<([a-z][a-z0-9]*)[^>]*?(\/?)>/i','<$1$2>', $text);
/* BBCode для ссылки вида [ url ]ссылка[/ url] */
$text = preg_replace("#\[url\][\s]*(http://([а-яёa-z\d][а-яёa-z\d\-]*\.)+[а-яёa-z]{2,6}(/([а-яё\w\-\.]*[а-яё\w\-/]{1})*(\?(([a-z][\w\-]*)?(=(%[a-z\d]{2}|[\w\-\.\+])*)?)?(&(amp;)?(([a-z][\w\-]*)?(=(%[a-z\d]{2}|[\w\-\.\+])*)?)?)*)?)?)[\s]*\[\/url\]#isu",'<a href="\\1" target="_blank">\\1</a>',$text);
?>
|
| |
|
|
|
|
|
|
|
для: tima2010
(17.03.2012 в 16:57)
| | Проблема очистки html актуальна и сейчас.
Вот например статья HtmlCleaner про очистку html от ненужных тегов и атрибутов тегов.
В статье описан класс для решения вашей задачи. Делает то же самое.
Но не использует регулярных выражений для выделения атрибутов тегов.
Для удаления атрибутов использован DOMDocument. Кроме того, есть возможность удалять JavaScript из атрибутов href.
Очень гибкая настройка работы класса. | |
|
|
|