Точно и подробно про защиту от инъекций в php, mysql?

Здравствуйте! Перерыл кучу разной информации по поводу защиты вводимых пользователями данных, но точного объяснения, как нужно правильно защищаться не нашел. На форумах, гайдах и прочих источниках информации, всегда всё сводится к одному - человек пишет гайд, как "правильно" нужно защищаться, потом в комментариях люди пишут, что он дурак и только учит людей плохому. В итоге, нормально и точной информации никто не оставил.
Возьмём за пример такую задачу, самую элементарную и о которой постоянно говорят - защита пароля, логина на форме авторизации. Кто-то пишет, что нужно делать так:
$login = trim($_GET['login']);
	$login = strip_tags($login);
	$login = mysqli_real_escape_string($mysqli, $login);

А кто-то, что нужно так:
$login = $_GET['login'];
	$login = mysqli_real_escape_string($mysqli, $login);

В итоге, все эти варианты "забраковывают". Ответа я так и не получил. К тому же, даже если "гуглить" информацию по моему запросу, на первых местах постоянно статьи, с минусовым рейтингом(С хабра, например). Возможно, вопрос очень простой, но перечитав все статьи, я окончательно запутался. Может ли кто-нибудь дать ответ по этому вопросу? Прошу не писать про то, что нужно использовать готовые CMS и прочие решения.
Спасибо!
  • Вопрос задан
  • 2783 просмотра
Решения вопроса 1
delphinpro
@delphinpro Куратор тега PHP
frontend developer
$login = trim($_GET['login']);
$login = strip_tags($login);
$login = mysqli_real_escape_string($mysqli, $login);

Почему вы думаете, что нужно менять логин пользователя, если она захотел именно такой? хочет быть <script> - пусть будет. Не ограничивайте.

нужно различать sql-инъекцию и xss-атаку
т.е. если мы пишем в базу, то
$login = mysqli_real_escape_string($mysqli, $login);
query( insert into ... );

Далее выводим на страницу
$login = query( select from ... );
echo htmlspeialchars($login);

И все счастливы.

Если у вас будет время, напишите, пожалуйста, как бы Вы написали данный код. Мне просто интересно, посмотреть на правильно реализованный код.

Код писать лень, хотя я там выше в принципе его уже написал =) только вместо mysqli_real_escape_string в реальном коде я бы использовал подготовленные выражения (и PDO вместо mysqli, хотя тут наверное, дело вкуса).
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Проверка входящих переменных делается в 2 этапа:
1. validfilter() - Проверяем входные переменные от пользователей на валидность через Regex.
2. mysql_escape_mimic() - Экранируем перед помещением в выражение запроса к БД.
(код рабочий!)
//----------------------
function mysql_escape_mimic($inp) {
//from: http://php.net/manual/en/function.mysql-real-escape-string.php#101248
    if(is_array($inp))
        return array_map(__METHOD__, $inp);
    if(!empty($inp) && is_string($inp)) {
        return str_replace(array('\\', "\0", "\n", "\r", "'", '"', "\x1a"), array('\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'), $inp);
    }
    return $inp;
}

function validfilter($value,$regexp,$flags='usi') {
  if (preg_match('/'.$regexp.'/'.$flags, $value,$result) 
       && $result[0]===$value) return $value;  
  else return false;
}
$charset=array(
   'bad'=>'\x00-\x09\x0B\x0C\x0E-\x1F\x80-\xFF',
   'sql'=>'\x00\x0a\x0c\x1a\x22\x27\x5c',
    'en'=>'a-zA-Z',
    'ru'=>'а-яА-ЯёЁ',
   'digits'=>'0-9',
   'num'=>'0-9-.',
   'space'=>'\s',
);
$filter=array(
//login - любой символ, кроме непечатных, sql-"опасных" и пробелов; от 3 до 20 знаков.
 'login'=>"^"."([^".$charset['bad'].$charset['sql'].$charset['space']."]{3,20})$", 
);
//----------------------
$login = validfilter($_REQUEST['login'],$filter['login']);

Затем (при необходимости), для безопасной работы с базой, используем: mysql_escape_mimic()
В данном случае, в $login экранировать будет нечего, т.к. мы сразу проверили это через добавление набора $charset['sql'] в фильтр проверки.
Поэтому, $login можно сразу использовать в sql-запросе без каких либо опасений.
Ответ написан
@xfg
Подготовленные запросы.

Старайся вообще читать по меньше хабр и побольше документации от разработчиков инструмента, которым пользуешься. Хабр и другие блог платформы это субъективное мнение автора. Не надежный источник информации.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы