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

S
На сайте с 24.09.2018
Offline
6
274

Я не занимаюсь технической поддержкой сайтов, но так уж сложилось, что ко мне часто обращаются за помощью. С одной стороны отказывать неудобно, да и не выгодно с коммерческой точки зрения, с другой за большое спасибо в магазине тоже не расплатишься. Поэтому я решил написать универсальное решение, но столкнулся с некоторыми проблемами.

Суть решения заключается в том, чтобы отловить данные POST, GET, 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($_POST 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);
$_POST[$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);
//Преобразуеv все возможные символы в соответствующие HTML-сущности
$v = htmlentities($v, ENT_QUOTES, "UTF-8");
$v = htmlspecialchars($v, ENT_QUOTES);
//Перезаписываем GET массив
$_POST[$k] = $v;
}

}

Тоже самое я сделал по аналогии с _GET и _COOKIE

Основные недостатки.

1) У меня так и не вышло обработать, а точнее перезаписать их внутри функции и передать _POST, _GET и _COOKIE в качестве переменных, а главное, как следствие, обработать многомерные массивы данных рекурсивно. Соответственно $_POST[][], $_POST[][][] и тд уже обработать не выйдет и каждый такой массив надо вставлять отдельно. Массив может быть бесконечно большой, а код получится бесконечно громозкий.

2) Не охота убирать функцию mysql_real_escape_string ведь никогда не знаешь, где ее забыли упомянуть, но возникает проблема излишнего экранирования символов.

3) strip_tags удаляет все теги. Мне бы не хотелось убирать все, а лишь самые опасные теги, но беда в том, что в дополнительных параметрах можно указать только теги, которые нужно оставить. Конечно, можно использовать регулярные выражения, но к сожалению, нет уверенности в том, что не забудешь что-нибудь важное, поэтому если у кого-то есть отличная замена этому, то предлагаю собрать все в кучу и избавиться от strip_tags

4) Ну и жду других советов по данному вопросу.

T7
На сайте с 19.09.2018
Offline
63
#1
superpupervest:
Соответственно $_POST[][], $_POST[][][] и тд уже обработать не выйдет и каждый такой массив надо вставлять отдельно

Не надо.


$_POST = [ 'a'=>'sdfsfsdf sdffdf',
'b'=>[ ['dgdgdg','dfgdfg', 'sdffdf dfs f sf'],
['dgdgdg','dfgdfg']
]
];

$this->arr_check ( $_POST, function($v){ return 'Chanded: ' . md5($v); } );

private function arr_check ( array &$array, callable $callback )
{
foreach ($array as $k => $v) {
if ( is_array($v) ) {
$this->arr_check( $array[$k], $callback );
} else {
$array[$k] = $callback($v);
}
}
}

Результат


Array
(
[a] => Chanded: 59f77f5632f2c4db082263bbb774984a
=> Array
(
[0] => Array
(
[0] => Chanded: 760ddc88c5482659e22463fee24272d0
[1] => Chanded: 8d509c28896865f8640f328f30f15721
[2] => Chanded: 7ac641885e9e529eab3b3dbc515fb239
)

[1] => Array
(
[0] => Chanded: 760ddc88c5482659e22463fee24272d0
[1] => Chanded: 8d509c28896865f8640f328f30f15721
)

)

)

SeVlad
На сайте с 03.11.2008
Offline
1609
#2
superpupervest:
Универсальная защита от xss-атак и sql-инъекций

Ух.. уже 6 лет прошло /ru/forum/774368, а как вчера.. :)

ЗЫ. Кто хочет поржать - рекомендую полистать. Топик - классика жанра.

Делаю хорошие сайты хорошим людям. Предпочтение коммерческим направлениям. Связь со мной через http://wp.me/P3YHjQ-3.
C
На сайте с 11.03.2017
Offline
18
#3

Для защиты от SQL-инъекций используйте подготавливаемые запросы.

Для защиты от XSS используйте функции filter_*

Прямое обращение к суперглобальным массивам - от лукавого.

Перезапись суперглобального массива $_POST - вообще тянет на уголовку.

Расширение mysql_ вроде ещё Иван Грозный запретил.

И вопрос: а что если в коде для получения переменных запроса используется filter_input/filter_input_array? Будет тогда Ваш код работать?

S
На сайте с 30.09.2016
Offline
469
#4
c00x:
Перезапись суперглобального массива $_POST - вообще тянет на уголовку.

Мне как-то нужно было добавить функциональность в самописный движок, и для этого требовалось записывать в БД данные типа $_POST['name'][]. Написал, проверяю - шиш с маслом. Начал копать - оказывается, умник, который написал тот движок, на входе перезаписывал $_POST через array_walk(), и все мои переменные благополучно уничтожались. :(

Отпилю лишнее, прикручу нужное, выправлю кривое. Вытравлю вредителей.

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий