[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Экранирование некоторых HTML тегов
Страницы: 1, 2, 3, 4
Arh
Хм, может можно это как то через XML реализовать?

_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
killer8080
Цитата (FatCat @ 8.11.2014 - 23:23)
Цитата (Arh @ 8.11.2014 - 22:24)можно ли как то навредить, передать в ссылке картинки какию нибудь хрень?
Внедрить джаваскрипт, ворующий куки.

Эти старые всем известные дыры, на сегодняшний день закрыты во всех современных браузерах. Псевдопротокол javascript:// теперь контестно зависимый, разрешен не во всех урл. В картинках, ифреймах, стилях и т.п. он не сработает. В ФФ он даже в адресной строке запрещён.

Цитата (Arh @ 8.11.2014 - 22:24)
Хм, а можно ли как то навредить, передать в ссылке картинки какию нибудь хрень?
Если да, то все ссылки на картинки надо обрабатывать, сохранять картинки к себе на сервер через GD и отдавать картинку уже с сервера? Хотя на форуме прямые ссылки на картинки
такая XSS уязвимость была в IE6, потом её профиксили, на сегодняшний день вроде нет таких дырявых браузеров.
Arh
killer8080
Успокоил )

_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
Arh
В общем упер где то код, пофиксил, работает почти идеально =)
Может кому пригодится.

class text {
#htmlspecialchars с исключениями
static function htmlspecialchars ($text = '',array $tags = array(),$del=false) {
if(!empty($tags)) {
foreach($tags as $key=>$value){
if(is_array($value)) {
for($i=0; $i<count($value); $i++){
$tags[$key][$i] = strtolower($tags[$key][$i]);
}
}
else {
$tags[$value] = array();
unset($tags[$key]);
}
}


$tags = array_change_key_case($tags);
$open_tags_stack = array();
$code = false;

//Разбиваем полученный код на учатки простого текста и теги
$seg = array();
while(preg_match('/<[^<>]+>/siu', $text, $matches, PREG_OFFSET_CAPTURE)){
if($matches[0][1]) {
$seg[] = array('seg_type'=>'text', 'value'=>substr($text, 0, $matches[0][1]));
}
$seg[] = array('seg_type'=>'tag', 'value'=>$matches[0][0]);
$text = substr($text, $matches[0][1]+strlen($matches[0][0]));
}
if($text != '') {
$seg[] = array('seg_type'=>'text', 'value'=>$text);
}

//Обрабатываем полученные участки
for($i=0; $i<count($seg); $i++){

//Если участок является простым текстом экранируем в нем спец. символы HTML
if($seg[$i]['seg_type'] == 'text') {
$seg[$i]['value'] = htmlentities($seg[$i]['value'], ENT_QUOTES, 'UTF-8');

//Если участок является тэгом...
} elseif($seg[$i]['seg_type'] == 'tag'){

//находим тип тэга(открывающий/закрывающий), имя тэга, строку атрибутов
preg_match('#^<\s*(/)?\s*([a-z0-9]+)(.*?)>$#siu', $seg[$i]['value'], $matches);
$matches[1] = $matches[1] ? $seg[$i]['tag_type']='close' : $seg[$i]['tag_type']='open';
$seg[$i]['tag_name'] = strtolower($matches[2]);
if(($seg[$i]['tag_name']=='code') && ($seg[$i]['tag_type']=='close')) {
$code = false;
}

//Если этот тэг находится внутри конструкции <code></code> рассматриваем его не как тэг, а как простой текст
if($code) {
$seg[$i]['seg_type'] = 'text';
$i--;
continue;
}

//если тэг открывающий
if($seg[$i]['tag_type'] == 'open') {

//если тэг недопустимый экранируем/удаляем его
if(!array_key_exists($seg[$i]['tag_name'], $tags)){
if($del) {
$seg[$i]['action'] = 'del';
} else {$seg[$i]['seg_type'] = 'text';
$i--;
continue;
}

//если допустимый
} else {

//находим атрибуты и оставляем только допустимые
preg_match_all('!([a-z]+)\s*=\s*([\'\"])\s*([a-zA-Zа-яА-Я0-9._@=?:&\-#/;"]*)\s*\2!siu', $matches[3], $attr_m, PREG_SET_ORDER);
$attr = array();
foreach($attr_m as $arr) {
if(in_array(strtolower($arr[1]), $tags[$seg[$i]['tag_name']])) {
$attr[strtolower($arr[1])] = htmlentities($arr[3], ENT_QUOTES, 'UTF-8');
}
}

$seg[$i]['attr'] = $attr;

if($seg[$i]['tag_name'] == 'code') {
$code = true;
}

//если тэг требует закрывающего тэга заносим в стек открывающих тэгов
if(!count($tags[$seg[$i]['tag_name']]) || ($tags[$seg[$i]['tag_name']][count($tags[$seg[$i]['tag_name']])-1] != false)) {
array_push($open_tags_stack, $seg[$i]['tag_name']);
}
}


//если тэг закрывающий
} else {

//если тэг допустимый...
if(array_key_exists($seg[$i]['tag_name'], $tags) && (!count($tags[$seg[$i]['tag_name']]) || ($tags[$seg[$i]['tag_name']][count($tags[$seg[$i]['tag_name']])-1] != false))) {

if($seg[$i]['tag_name'] == 'code') {
$code = false;
}

//если стек открывающих тэгов пуст экранируем/удаляем этот тэг
//...или в нем нет тэга с таким именем

if((count($open_tags_stack) == 0) || (!in_array($seg[$i]['tag_name'], $open_tags_stack))) {
if($del) {
$seg[$i]['action'] = 'del';
} else {$seg[$i]['seg_type'] = 'text';
$i--;
continue;
}

//в противном случае...
} else {

//если этот тэг не соответствует последнему из стека открывающих тэгов добавляем правильный закрывающий тэг
$tn = array_pop($open_tags_stack);
if($seg[$i]['tag_name'] != $tn){
array_splice($seg, $i, 0, array(array('seg_type'=>'tag', 'tag_type'=>'close', 'tag_name'=>$tn, 'action'=>'add')));
}
}


//если тэг недопустимый удаляем его
} else {
if($del) {
$seg[$i]['action'] = 'del';
} else {$seg[$i]['seg_type'] = 'text';
$i--;
continue;
}
}
}
}
}


//Закрываем оставшиеся в стеке тэги
foreach(array_reverse($open_tags_stack) as $value) {
array_push($seg, array('seg_type'=>'tag', 'tag_type'=>'close', 'tag_name'=>$value, 'action'=>'add'));
}

//Собираем профильтрованный код и возвращаем его
$filtered_HTML = '';
foreach($seg as $segment) {
if($segment['seg_type'] == 'text') {
$filtered_HTML .= $segment['value'];
} elseif(($segment['seg_type'] == 'tag') && (@$segment['action'] != 'del')) {
if($segment['tag_type'] == 'open') {
$filtered_HTML .= '<'.$segment['tag_name'];
if(is_array($segment['attr'])){
foreach($segment['attr'] as $attr_key=>$attr_val){
$filtered_HTML .= ' '.$attr_key.'="'.$attr_val.'"';
}
}

if (count($tags[$segment['tag_name']]) && ($tags[$segment['tag_name']][count($tags[$segment['tag_name']])-1] == false)) {
$filtered_HTML .= " /";
}
$filtered_HTML .= '>';
} elseif($segment['tag_type'] == 'close'){
$filtered_HTML .= '</'.$segment['tag_name'].'>';
}
}
}


return $filtered_HTML;
} else {
return htmlentities($text);
}
}
}


$text = '<blockquote>цитата</blockquote><a href="/" title="ссылка">ссылка</a>';
$text = text::htmlspecialchars($text,array(
'blockquote',
'a' => array('href','title')
));


echo $text;


_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
Быстрый ответ:

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