Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум Регулярные Выражения

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Удаление атрибутов у тегов
 
 автор: tima2010   (17.03.2012 в 16:57)   письмо автору
 
 

Привет!

Застрял я на ситуации которая позволяет посетителям публиковать новости.
К публикации подключен 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=""

  Ответить  
 
 автор: ladan   (19.03.2012 в 01:57)   письмо автору
 
   для: 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, тожно добавить в регулярку

  Ответить  
 
 автор: tima2010   (20.03.2012 в 15:46)   письмо автору
 
   для: 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);



видимо придется просто отключить теги... мде

  Ответить  
 
 автор: Sfinks   (20.03.2012 в 20:15)   письмо автору
 
   для: tima2010   (20.03.2012 в 15:46)
 

Что вы пытаетесь сделать? Защититься? Ну так вы уже это сделали. htmlspecialchars() преобразует специальные символы в HTML-сущности и ни один скрипт прописанный пользователем не сработает на вашей странице. Если же вы хотите использовать теги для форматирования, то обычно для этого применяют так называемые bbCode. Т.е. Пользователь пишет теги не в < >, а в [ ], также как и здесь при форматировании сообщения, а скрипт потом все что разрешено заменяет на реальные теги. Соответственно что не разрешено вами лично так и останется в квадратных скобках и никак не будет функционировать.

  Ответить  
 
 автор: tima2010   (20.03.2012 в 21:07)   письмо автору
 
   для: Sfinks   (20.03.2012 в 20:15)
 

Используется wysiwyg редактор, отформатированный текст сразу отображается без bbcode.
Не хочется заставлять пользователя использовать [ b ] текст [/ b ], аудитория не та
Как известно в wisiwyg редактор можно скопировать ссылку с какого либо сайта и вставить в окно редактора. Все атрибуты которые были в скопированной ссылке сохраняются.
Поэтому думаю как их отрубить.
Либо придется использовать вырезку всех атрибутов и позволить использовать теги у которых атрибуты не обязательны. А ссылку кому надо писать в виде bbcode [ url href='' ] ссылка [/ url ]

  Ответить  
 
 автор: ladan   (20.03.2012 в 22:02)   письмо автору
 
   для: tima2010   (20.03.2012 в 21:07)
 

у меня на форуме стоит редактор tinyMCE. Работает как у вас походу и такие же проблемы. Если бы яваскрипт знал, то лучше бы сделал как на этом форуме, через bbcode. Может просто mysql_real_escape_string обрабатывать переменные? Я по началу тоже думал вырезать все лишние атрибуты и теги, но потом понял, что не буду ничего такого делать, а буду сразу банить людей за какие-нибудь пакости :)

  Ответить  
 
 автор: tima2010   (20.03.2012 в 22:14)   письмо автору
 
   для: 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); // у всех тегов вырезаем атрибуты
?>

  Ответить  
 
 автор: Sfinks   (20.03.2012 в 23:00)   письмо автору
 
   для: ladan   (20.03.2012 в 22:02)
 

> а буду сразу банить людей за какие-нибудь пакости
Не хотелось бы каркать, но может так случиться, что банить будет просто некого, т.к. БД будет удалена, а вместо сайта будет редирект на какую-нибудь порнуху )

  Ответить  
 
 автор: tima2010   (20.03.2012 в 23:03)   письмо автору
 
   для: 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 по сути не может содержать пробелов, если это так то очень хорошо :)

  Ответить  
 
 автор: Sfinks   (20.03.2012 в 23:47)   письмо автору
 
   для: tima2010   (20.03.2012 в 23:03)
 

Да, верно.
[\s]* - 0 или более пробелов
[\S]+ - 1 или более НЕ пробелов.
только [ ] тут абсолютно не нужны, а [\S]+ я бы заменил на РВ описывающее УРЛ.

  Ответить  
 
 автор: Sfinks   (20.03.2012 в 23:53)   письмо автору
 
   для: tima2010   (20.03.2012 в 23:03)
 

isU - вы этим что хотели сказать? "i", "s" понятно. "U" - вы же не имели ввиду УТФ? ) потому что УТФ обозначается "u". А что значит "U" я не помню и сейчас чет не получается найти. Но однозначно не УТФ.

  Ответить  
 
 автор: tima2010   (21.03.2012 в 08:17)   письмо автору
 
   для: Sfinks   (20.03.2012 в 23:53)
 

спасибо!
Странно работает и с U и с u

  Ответить  
 
 автор: tima2010   (21.03.2012 в 09:00)   письмо автору
 
   для: 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]';
и прочей дребедени

а найти толковый валидатор ссылок не получается...

  Ответить  
 
 автор: Sfinks   (21.03.2012 в 09:46)   письмо автору
 
   для: 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]+

  Ответить  
 
 автор: tima2010   (21.03.2012 в 10:04)   письмо автору
 
   для: Sfinks   (21.03.2012 в 09:46)
 

Большое спасибо

  Ответить  
 
 автор: ladan   (21.03.2012 в 11:18)   письмо автору
 
   для: Sfinks   (20.03.2012 в 23:00)
 

ну тогда почаще бэкапы делать :)

  Ответить  
 
 автор: tima2010   (21.03.2012 в 11:36)   письмо автору
 
   для: ladan   (21.03.2012 в 11:18)
 

Что то не так с рег. выражением?

  Ответить  
 
 автор: ladan   (21.03.2012 в 17:28)   письмо автору
 
   для: tima2010   (21.03.2012 в 11:36)
 

да не, все в норме )

  Ответить  
 
 автор: Гость   (21.03.2012 в 10:33)   письмо автору
 
   для: tima2010   (17.03.2012 в 16:57)
 

Разбейте задачу на подзадачи:
1. Находим все теги.
2. Удаляем не разрешенные теги.
3. Для каждого тега находим все атрибуты
4. Удаляем не разрешенные атрибуты, для не левых - проверяем корректность заполнения, если что-то не так - вырезаем и их.

Обратите внимание - лучше всего по умолчанию запретить все теги/атрибуты, а уже потом разрешить только необходимые - это гораздо проще чем перечислять все теги/атрибуты, которые мы хотим запретить и при этом забыть про пару-другую, через которые в итоге и поломают :)

PS: присмотритесь к функции "preg_replace_callback"

  Ответить  
 
 автор: tima2010   (21.03.2012 в 11:02)   письмо автору
 
   для: Гость   (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);
?>

  Ответить  
 
 автор: vasiatka   (18.02.2014 в 21:23)   письмо автору
 
   для: tima2010   (17.03.2012 в 16:57)
 

Проблема очистки html актуальна и сейчас.
Вот например статья HtmlCleaner про очистку html от ненужных тегов и атрибутов тегов.
В статье описан класс для решения вашей задачи. Делает то же самое.
Но не использует регулярных выражений для выделения атрибутов тегов.
Для удаления атрибутов использован DOMDocument. Кроме того, есть возможность удалять JavaScript из атрибутов href.
Очень гибкая настройка работы класса.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования