Pull to refresh

Универсальная защита от xss-атак и sql-инъекций

Reading time 5 min
Views 13K
Так сложилось, что вот уже который год мне приходится заниматься технической поддержкой хостинга, а также поддержкой сайтов, к которым я имею довольно косвенное отношение. А так как администраторы довольно часто сталкиваются с разного рода атаками на свои сайты, не имея при этом возможности нанять специалиста, мне пришло в голову придумать единое и универсальное решение для всех сайтов, которое бы помогло им защитить свой сайт без особых усилий. И хотя в нем есть еще немало минусов и нюансов, которые мне пока не удалось решить, тем не менее это единственное на данный момент решение, которое позволяет обезопасить сайт изнутри, не обращаясь к разного рода плагинам и модулям, которые нужно устанавливать извне и которое даже малоопытный разработчик сайтов способен установить и настроить у себя на сайте. Суть данного решения заключается в том, чтобы обработать данные переданные методами GET, POST и/или COOKIE, еще до момента обработки и записи их самих непосредственно в базу данных.

В этой статье я приведу примеры использования и недостатки того или иного метода.

Вот собственно сам код

$jsxss="onabort,oncanplay,oncanplaythrough,ondurationchange,onemptied,onended,onerror,onloadeddata,onloadedmetadata,onloadstart,onpause,onplay,onplaying,onprogress,onratechange,onseeked,onseeking,onstalled,onsuspend,ontimeupdate,onvolumechange,onwaiting,oncopy,oncut,onpaste,ondrag,ondragend,ondragenter,ondragleave,ondragover,ondragstart,ondrop,onblur,onfocus,onfocusin,onfocusout,onchange,oninput,oninvalid,onreset,onsearch,onselect,onsubmit,onabort,onbeforeunload,onerror,onhashchange,onload,onpageshow,onpagehide,onresize,onscroll,onunload,onkeydown,onkeypress,onkeyup,altKey,ctrlKey,shiftKey,metaKey,key,keyCode,which,charCode,location,onclick,ondblclick,oncontextmenu,onmouseover,onmouseenter,onmouseout,onmouseleave,onmouseup,onmousemove,onwheel,altKey,ctrlKey,shiftKey,metaKey,button,buttons,which,clientX,clientY,detail,relatedTarget,screenX,screenY,deltaX,deltaY,deltaZ,deltaMode,animationstart,animationend,animationiteration,animationName,elapsedTime,propertyName,elapsedTime,transitionend,onerror,onmessage,onopen,ononline,onoffline,onstorage,onshow,ontoggle,onpopstate,ontouchstart,ontouchmove,ontouchend,ontouchcancel,persisted,javascript";
$jsxss = explode(",",$jsxss);
foreach($_GET as $k=>$v)
{
	if(is_array($v))
	{
		foreach($v as $Kk=>$Vv)
		{
			$Vv = preg_replace ( "'<script[^>]*?>.*?</script>'si", "", $Vv );
			$Vv = str_replace($jsxss,"",$Vv);
			$Vv = str_replace (array("*","\\"), "", $Vv );
			$Vv = strip_tags($Vv);
			$Vv = htmlentities($Vv, ENT_QUOTES, "UTF-8");
			$Vv = htmlspecialchars($Vv, ENT_QUOTES);
			$_GET[$k][$Kk] = $Vv;
		}
	}
	ELSE
	{
		//Сначала удаляем любые скрипты для защиты от xss-атак
		$v = preg_replace ( "'<script[^>]*?>.*?</script>'si", "", $v );
		//Вырезаем все известные javascript события для защиты от xss-атак
		$v = str_replace($jsxss,"",$v);
		//Удаляем экранирование для защиты от SQL-инъекций
		$v = str_replace (array("*","\\"), "", $v );
		//Экранируем специальные символы в строках для использования в выражениях SQL
		$v = mysql_real_escape_string( $v );
		//Удаляем другие лишние теги.	
		$v = strip_tags($v);
		//Преобразуем все возможные символы в соответствующие HTML-сущности
		$v = htmlentities($v, ENT_QUOTES, "UTF-8");
		$v = htmlspecialchars($v, ENT_QUOTES);
		//Перезаписываем GET массив
		$_GET[$k] = $v;
	}
	
}

Вышеуказанный пример обрабатывает только GET запросы. Так что цикл необходимо повторить как минимум с POST и COOKIE. К сожалению мне так и не удалось выполнить данное решение рекурсивно в функции, и передать все нужные нам массивы $_GET, $_POST и $_COOKIE одновременно. А самое главное, что так и не удалось реализовать, так это рекурсивный обход многомерных массивов такого типа, что связано с особенностью передачи данных данных внутри функции, а также ограниченностью использования переменных переменных.

1) $v = preg_replace ( "'<script[^>]*?>.*?'si", "", $v );

Здесь мы удаляем явно не нужный javascript код. Функция может оказаться лишней, если Вы все таки позволяете передавать непосредственно сам код, не для его выполнения, а для ознакомления. Например на форумах.

2) $v = str_replace($jsxss,"",$v);

Функция аналогична первой, только в данном случае мы вырезаем события, которые можно использовать для xss-атак. Можно несколько модифицировать данное решение и вырезать не только само событие, но содержимое, которое к нему пытаются прикрепить. Но я пока не увидел в этом необходимости

3) $v = str_replace (array("*","\\"), "", $v );

А эти вредоностные символы, особенно обратная косая черта, могут стать причиной взлома Вашей SQL. Так как сам символ используется довольно редко, а его потенциальная опасность довольно велика, я решил уничтожить его на корню.

4) $v = mysql_real_escape_string( $v );

Использование этой функции может вызвать излишнее экранирование символов, ведь скорее всего он уже используется непосредственно при записи данных в базу, но с другой стороны, он как никто другой поможет защититься от sql-инъекций и защитит Ваши данные. При его использовании необходимо использовать функцию после подключения к базе данных. Также не будем забывать, что mysql_real_escape_string не используется в php 7, да и само использование подобных функций зависит от способа подключения. Например при подключении к базе через mysqli может понадобиться использовать функция mysqli_real_escape_string.

5) $v = strip_tags($v);

Strip_tags поможет удалить все ненужные теги. К сожалению, и нужные тоже. Вторым параметром можно указать теги, которые нужно оставить. Но беда в том, что нужных тегов так много, что перечислить их довольно проблематично, а что самое прискорбное, то бывают встречаются и такие теги, которые разработчики сайтов добавляют самостоятельно, для создания определенных функций на сайте. Конечно, было бы куда удобнее указать теги, которые нужно удалить, а не оставить. Но будем довольствоваться тем, что есть. К тому же для таких решений можно использовать регулярные выражения.

6) $v = htmlentities($v, ENT_QUOTES, «UTF-8»);

7) $v = htmlspecialchars($v, ENT_QUOTES);


Думаю, что эти две функции не нуждаются в представлении и одна аналогична другой, поэтому вполне достаточно использовать одну из них. Тем не менее и они далеко не всегда уместны.

На текущий момент это все, что мне удалось собрать. Если кому-то есть, чем дополнить данную статью, то буду только рад ;)

P.S. Для тех, кто хаит решение и предлагает использовать PDO, шаблонизаторы, разные серверные модули и тд. Я ни в коей мере не отрицаю, что данное решение имеет свои минусы, и где-то покорежит вывод и даже может повлиять на функционал, для чего и написал вначале поста о том, решение имеет свои недостатки.

Этот пост не для программистов, он для администраторов сайтов, которым не хватает знаний и опыта, чтобы изменить код изнутри. Для тех, кто не хочет, или не может, платить за доработку сайтов. Что часто бывает, когда разработчик делает сайты подешевле, на какой-нибудь недорогой, а часто и вовсе бесплатной CMS.

А чтобы такого не происходило необходимо разрабатывать свои сайты на надежных и проверенных CMS, с качественной техподдержкой. Наиболее подходящая и функциональная CMS для разработки подобных проектов это Битрикс. Заказывая у нас на https://wazzup. Хостинг и Лицензию Битрикс мы готовы выполнить настройку и установку магазина совершенно бесплатно.

Также прошу учесть, что у нас действует акция за покупку Лицензии Битрикс, до 6 месяцев хостинга бесплатно.

Наши клиенты выбирают Битрикс, так как это единственная крупнейшая система управления сайтами в РФ с огромной системой техподдержки и мощнейшим функционалом. Надежность Битрикс обусловлена не только временем, но и постоянной квалифицированной техподдержкой программистов, в отличии от бесплатных и недорогих CMS, разработкой и поддержкой которых занимаются постоянно меняющиеся энтузиасты, без большого опыта.
Tags:
Hubs:
-23
Comments 47
Comments Comments 47

Articles