В этом материале описывается правильная защита скриптов от хакеров, защита сайта от хакеров. Итак, перед большинством тех, кто когда-либо занимался разработкой скриптов на PHP, рано или поздно встаёт задача защиты от взлома, осуществляющегося через входные параметры скрипта (массивы $_GET и $_POST). 90% php-программистов решают этот вопрос фильтрацией содержимого: пишут большущие (и, как следствие, неэффективные) функции, вырезающие опасные данные. Однако все случаи невозможно описать в таких фунциях! Ни одна функция не может гарантировать, что она учитывает все возможные варианты инъекций. Между тем, существует способ решения, снимающий 95% атак. Основные моменты: 1. Разделяем защиту от sql-inj, XSS, CSRF по разным местам (не нужно объединять это всё в одну функцию) 2. Строгая типизация входных параметров (для чисел используем приведение к целому, для строк - mysql_escape_string). 3. При выводе всегда пользуем htmlspecialchars. 4. Больше никакой фильтрации не надо! Теперь чуть подробнее. sql-inj Внедрение SQL-кода (англ. SQL injection) — один из распространённых способов взлома сайтов и программ, работающих с базами данных, основанный на внедрении в запрос произвольного SQL-кода. Подробнее тут. От этой атаки защищаемся вначале выполнения скрипта (считайте, в самом верху). Решение: контролируем тип переменных. 1) Для чисел пользуем приведение к целому: $val = isset($_GET[$name]) ? (int)$_GET[$name] : 0; 2) Для строк: $val = mysql_real_escape_string($_GET[$name]); 3) В запросах даже целочисленные данные берём в одинарные кавычки. Код: mysql_query("SELECT id,name,etc FROM table WHERE num = '$val'"); Больше ничего! Никаких фильтров. XSS XSS (англ. Сross Site Sсriрting — «межсайтовый скриптинг») — тип уязвимости интерактивных информационных систем в вебе. XSS возникает, когда в генерируемые сервером страницы по какой-то причине попадают пользовательские скрипты. Специфика подобных атак заключается в том, что вместо непосредственной атаки сервера они используют уязвимый сервер в качестве средства атаки на клиента. Подробно тут. От этой атаки защищаемся при выводе любой переменной: $text = htmlspecialchars($text) Больше ничего CSRF CSRF (англ. Сross Site Request Forgery — «Подделка межсайтовых запросов», также известен как XSRF) — вид атак на посетителей веб-сайтов, использующий недостатки протокола HTTP. Если жертва заходит на сайт, созданный злоумышленником, от её лица тайно отправляется запрос на другой сервер (например, на сервер платёжной системы), осуществляющий некую вредоносную операцию (например, перевод денег на счёт злоумышленника). Для осуществления данной атаки, жертва должна быть авторизована на том сервере, на который отправляется запрос, и этот запрос не должен требовать какого-либо подтверждения со стороны пользователя, который не может быть проигнорирован или подделан атакующим скриптом. Подробнее тут. Защита: добавляем механизм сессий. Всё! Этого достаточно для того, чтобы защититься от взлома. Не надо никаких фильтров входящих данных. Привожу свои обёртки. PHP: <?php // Функции применяются ко входным параметрам // Защита от SQL-inj function NUMERIC_GET($name) { $val = isset($_GET[$name]) ? (int)$_GET[$name] : 0; $val = mysql_real_escape_string($val); return $val; } function STRING_GET($name) { $val = isset($_GET[$name]) ? mysql_real_escape_string($_GET[$name]) : ''; return $val; } function NUMERIC_POST($name) { $val = isset($_POST[$name]) ? (int)$_POST[$name] : 0; $val = mysql_real_escape_string($val); return $val; } function STRING_POST($name) { $val = isset($_POST[$name]) ? mysql_real_escape_string($_POST[$name]) : ''; return $val; } function ARRAY_STRING_POST($name) { $val = ''; if(isset($_POST[$name])) { $request = $_POST[$name]; if(is_array($request)) { foreach($request as $key => $value) { $request[$key] = mysql_real_escape_string($value); } $val = $request; } } return $val; } function ARRAY_STRING_GET($name) { $val = ''; if(isset($_GET[$name])) { $request = $_GET[$name]; if(is_array($request)) { foreach($request as $key => $value) { $request[$key] = mysql_real_escape_string($value); } $val = $request; } } return $val; } function ARRAY_NUMERIC_POST($name) { $val = 0; if(isset($_POST[$name])) { $request = $_POST[$name]; if(is_array($request)) { foreach($request as $key => $value) { $request[$key] = (int)$value; $request[$key] = mysql_real_escape_string($request[$key]); } $val = $request; } } return $val; } function ARRAY_NUMERIC_GET($name) { $val = 0; if(isset($_GET[$name])) { $request = $_GET[$name]; if(is_array($request)) { foreach($request as $key => $value) { $request[$key] = (int)$value; $request[$key] = mysql_real_escape_string($request[$key]); } $val = $request; } } return $val; } // Функция для всех выходных параметров // Защита от XSS function r_echos($text) { return htmlspecialchars($text); } function echos($text) { echo htmlspecialchars($text); } ?> PS: 100%ых способов защит не существует. (с)by Kesha
90% php-программистов решают этот вопрос фильтрацией содержимого: пишут большущие (и, как следствие, неэффективные) функции, вырезающие опасные данные. Как раз таки это не есть безопасным способом, используя его вы просто отводите себе глаза...
фильтрация содержимого + лимит ошибок и лимит совпадений запросов из личной базы запросов + ещё одна хитрость ( 2-3 бан ), пока ни кто не одна софтина не справилась, конечно в ручную опытный юзерь возможно и справится, но вопрос захочет ли он тратить своё время и наращивать себе гемор?)