PHP->HTML: проверить атрибуты HTML тегов (априори, парсинг HTML)
В данный момент я работаю над проектом, в котором любой пользователь извне может принять участие. В таких условиях приходиться внимательно следить за вводом HTML кода, поэтому я потратил достаточно много времени на написание функционала, отвечающего за фильтрацию пользовательского ввода.
Если нежелательные теги и можно отсеять, используя встроенную функцию PHP strip_tags(), то для проверки атрибутов разрешённых HTML тегов придётся изобретать свой велосипед. Для чтения атрибутов, их параметров, названия тегов можно использовать эту функцию:
Функция пройдётся по HTML-вводу и найдя теги (< и >) вернёт массив вида:
Этот массив можно использовать для замены нежелательных тегов, атрибутов и параметров (например style="padding: 5000px;") ;)
Второй, необязательный параметр, задаёт режим чтения. По умолчанию - мультибайтовый (подойдёт для UTF-8).
Простейший пример запуска после объявления функции:
Пример запуска, с отключением мультибайтовости:
- function read_htmlAttrs ($source, $mb = true)
- {
- $m = 'strlen';
- $m_s = 'substr';
- if ($mb)
- {
- $m = 'mb_'.$m;
- $m_s = 'mb_'.$m_s;
- }
- $srcLen = $m ($source);
- $mode = 'full_idle';
- for ($x=0; $x<=$srcLen; $x )
- {
- $s = $m_s ($source, $x, 1);
- if ($mode=='full_idle' && $s=='<')
- {
- if ($m_s ($source, $x, 2)!='</')
- $mode = 'read_tag_name';
- continue;
- }
- {
- if ($s=='>')
- {
- $mode = 'close_tag';
- continue;
- }
- {
- $mode='read_attr_name';
- continue;
- }
- $tmp['tagName'] .= $s;
- }
- {
- if ($s=='>')
- {
- $mode = 'close_tag';
- continue;
- }
- if ($s=='=')
- {
- $mode = 'read_param';
- continue;
- }
- $tmp['attrName'] .= $s;
- continue;
- }
- {
- {
- if ($s==' ') continue;
- $mode='read_attr_name';
- continue;
- }
- if ($s=='/') continue;
- if ($s=='>')
- {
- $mode = 'close_tag';
- continue;
- }
- $tmp['param'] .= $s;
- continue;
- }
- if ($mode=='close_tag')
- {
- $mode = 'full_idle';
- }
- }
- return $result;
- }
Это результат работы функции над:
<span ass="dev" dev="ass">ololo</span>
$source = read_htmlAtrrs ($_POST['content']);
$source = read_htmlAtrrs ($_POST['content'], 0);
nEcdyGgx 13 Augustа в 18:33 #
555
nEcdyGgx 13 Augustа в 18:34 #
555
nEcdyGgx 13 Augustа в 18:34 #
555
nEcdyGgx 13 Augustа в 18:34 #
555
nEcdyGgx 13 Augustа в 18:34 #
555
nEcdyGgx 13 Augustа в 18:34 #
-1 OR 2+438-438-1=0+0+0+1 --
nEcdyGgx 13 Augustа в 18:34 #
-1 OR 3+438-438-1=0+0+0+1 --
nEcdyGgx 13 Augustа в 18:34 #
-1 OR 3*2
nEcdyGgx 13 Augustа в 18:35 #
-1 OR 3*2>(0+5+438-438) --
nEcdyGgx 13 Augustа в 18:35 #
-1 OR 2+380-380-1=0+0+0+1
nEcdyGgx 13 Augustа в 18:35 #
-1 OR 3+380-380-1=0+0+0+1
nEcdyGgx 13 Augustа в 18:35 #
-1 OR 3*2
nEcdyGgx 13 Augustа в 18:35 #
-1 OR 3*2>(0+5+380-380)
nEcdyGgx 13 Augustа в 18:35 #
-1' OR 2+799-799-1=0+0+0+1 --
nEcdyGgx 13 Augustа в 18:35 #
-1' OR 3+799-799-1=0+0+0+1 --
nEcdyGgx 13 Augustа в 18:35 #
-1' OR 3*2
nEcdyGgx 13 Augustа в 18:35 #
-1' OR 3*2>(0+5+799-799) --
nEcdyGgx 13 Augustа в 18:35 #
-1' OR 2+393-393-1=0+0+0+1 or 'AX5Wjz3k'='
nEcdyGgx 13 Augustа в 18:35 #
-1' OR 3+393-393-1=0+0+0+1 or 'AX5Wjz3k'='
nEcdyGgx 13 Augustа в 18:35 #
-1' OR 3*2
nEcdyGgx 13 Augustа в 18:35 #
-1' OR 3*2>(0+5+393-393) or 'AX5Wjz3k'='
nEcdyGgx 13 Augustа в 18:35 #
-1" OR 2+767-767-1=0+0+0+1 --
nEcdyGgx 13 Augustа в 18:35 #
-1" OR 3+767-767-1=0+0+0+1 --
nEcdyGgx 13 Augustа в 18:35 #
-1" OR 3*2
nEcdyGgx 13 Augustа в 18:35 #
-1" OR 3*2>(0+5+767-767) --
nEcdyGgx 13 Augustа в 18:35 #
if(now()=sysdate(),sleep(15),0)
nEcdyGgx 13 Augustа в 18:35 #
0'XOR(if(now()=sysdate(),sleep(15),0))XOR'Z
nEcdyGgx 13 Augustа в 18:35 #
0"XOR(if(now()=sysdate(),sleep(15),0))XOR"Z
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 13 Augustа в 18:35 #
-1; waitfor delay '0:0:15' --
nEcdyGgx 13 Augustа в 18:35 #
-1); waitfor delay '0:0:15' --
nEcdyGgx 13 Augustа в 18:35 #
1 waitfor delay '0:0:15' --
nEcdyGgx 13 Augustа в 18:35 #
KTVKECp6'; waitfor delay '0:0:15' --
nEcdyGgx 13 Augustа в 18:35 #
-5 OR 40=(SELECT 40 FROM PG_SLEEP(15))--
nEcdyGgx 13 Augustа в 18:35 #
-5) OR 924=(SELECT 924 FROM PG_SLEEP(15))--
nEcdyGgx 13 Augustа в 18:35 #
-1)) OR 307=(SELECT 307 FROM PG_SLEEP(15))--
nEcdyGgx 13 Augustа в 18:35 #
N6mJKu1g' OR 877=(SELECT 877 FROM PG_SLEEP(15))--
nEcdyGgx 13 Augustа в 18:35 #
8zZ1pBTB') OR 165=(SELECT 165 FROM PG_SLEEP(15))--
nEcdyGgx 13 Augustа в 18:35 #
2cQmkwDM')) OR 805=(SELECT 805 FROM PG_SLEEP(15))--
nEcdyGgx 13 Augustа в 18:35 #
555*DBMS_PIPE.RECEIVE_MESSAGE(CHR(99)||CHR(99)||CHR(99),15)
nEcdyGgx 13 Augustа в 18:35 #
555'||DBMS_PIPE.RECEIVE_MESSAGE(CHR(98)||CHR(98)||CHR(98),15)||'
nEcdyGgx 13 Augustа в 18:35 #
1'"
nEcdyGgx 13 Augustа в 18:35 #
@@yAeon
nEcdyGgx 13 Augustа в 18:47 #
555
nEcdyGgx 13 Augustа в 18:50 #
555
nEcdyGgx 13 Augustа в 18:50 #
555
nEcdyGgx 13 Augustа в 18:50 #
555
nEcdyGgx 13 Augustа в 18:50 #
555
nEcdyGgx 13 Augustа в 18:50 #
-1 OR 2+46-46-1=0+0+0+1 --
nEcdyGgx 13 Augustа в 18:50 #
-1 OR 3+46-46-1=0+0+0+1 --
nEcdyGgx 13 Augustа в 18:50 #
-1 OR 3*2
nEcdyGgx 13 Augustа в 18:50 #
-1 OR 3*2>(0+5+46-46) --
nEcdyGgx 13 Augustа в 18:50 #
-1 OR 2+718-718-1=0+0+0+1
nEcdyGgx 13 Augustа в 18:50 #
-1 OR 3+718-718-1=0+0+0+1
nEcdyGgx 13 Augustа в 18:50 #
-1 OR 3*2
nEcdyGgx 13 Augustа в 18:50 #
-1 OR 3*2>(0+5+718-718)
nEcdyGgx 13 Augustа в 18:50 #
-1' OR 2+748-748-1=0+0+0+1 --
nEcdyGgx 13 Augustа в 18:50 #
-1' OR 3+748-748-1=0+0+0+1 --
nEcdyGgx 13 Augustа в 18:50 #
-1' OR 3*2
nEcdyGgx 13 Augustа в 18:50 #
-1' OR 3*2>(0+5+748-748) --
nEcdyGgx 13 Augustа в 18:50 #
-1' OR 2+606-606-1=0+0+0+1 or 'vLk8NaNI'='
nEcdyGgx 13 Augustа в 18:50 #
-1' OR 3+606-606-1=0+0+0+1 or 'vLk8NaNI'='
nEcdyGgx 13 Augustа в 18:50 #
-1' OR 3*2
nEcdyGgx 13 Augustа в 18:50 #
-1' OR 3*2>(0+5+606-606) or 'vLk8NaNI'='
nEcdyGgx 13 Augustа в 18:50 #
-1" OR 2+296-296-1=0+0+0+1 --
nEcdyGgx 13 Augustа в 18:50 #
-1" OR 3+296-296-1=0+0+0+1 --
nEcdyGgx 13 Augustа в 18:50 #
-1" OR 3*2
nEcdyGgx 13 Augustа в 18:50 #
-1" OR 3*2>(0+5+296-296) --
nEcdyGgx 13 Augustа в 18:50 #
if(now()=sysdate(),sleep(15),0)
nEcdyGgx 13 Augustа в 18:50 #
0'XOR(if(now()=sysdate(),sleep(15),0))XOR'Z
nEcdyGgx 13 Augustа в 18:50 #
0"XOR(if(now()=sysdate(),sleep(15),0))XOR"Z
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 13 Augustа в 18:50 #
-1; waitfor delay '0:0:15' --
nEcdyGgx 13 Augustа в 18:50 #
-1); waitfor delay '0:0:15' --
nEcdyGgx 13 Augustа в 18:50 #
1 waitfor delay '0:0:15' --
nEcdyGgx 13 Augustа в 18:50 #
49IB4q9o'; waitfor delay '0:0:15' --
nEcdyGgx 13 Augustа в 18:50 #
-5 OR 569=(SELECT 569 FROM PG_SLEEP(15))--
nEcdyGgx 13 Augustа в 18:50 #
-5) OR 681=(SELECT 681 FROM PG_SLEEP(15))--
nEcdyGgx 13 Augustа в 18:50 #
-1)) OR 350=(SELECT 350 FROM PG_SLEEP(15))--
nEcdyGgx 13 Augustа в 18:50 #
TX77vyov' OR 808=(SELECT 808 FROM PG_SLEEP(15))--
nEcdyGgx 13 Augustа в 18:50 #
fOQrttSU') OR 924=(SELECT 924 FROM PG_SLEEP(15))--
nEcdyGgx 13 Augustа в 18:50 #
SfdHs7Hq')) OR 50=(SELECT 50 FROM PG_SLEEP(15))--
nEcdyGgx 13 Augustа в 18:50 #
555*DBMS_PIPE.RECEIVE_MESSAGE(CHR(99)||CHR(99)||CHR(99),15)
nEcdyGgx 13 Augustа в 18:50 #
555'||DBMS_PIPE.RECEIVE_MESSAGE(CHR(98)||CHR(98)||CHR(98),15)||'
nEcdyGgx 13 Augustа в 18:50 #
1'"
nEcdyGgx 13 Augustа в 18:50 #
@@vkgzj