Задать вопрос

Точно и подробно про защиту от инъекций в 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 и прочие решения.
Спасибо!
  • Вопрос задан
  • 2812 просмотров
Подписаться 8 Оценить 1 комментарий
Помогут разобраться в теме Все курсы
  • Skillbox
    Веб-разработчик на PHP
    9 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Решения вопроса 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
Подготовленные запросы.

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

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

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
от 200 000 до 290 000 ₽