Здравствуйте не могли б вы мне помочь разобраться в защите сайта от Sql инъекций. Я защищаю сайт вот таким образом: 1. Текстовые поля Код (Text): $_POST['str']= (string) $_POST['str'];//Указываем тип $_POST['str']=addslashes($_POST['str']);//экранируем $_POST['str']=str_replace("\\","",$_POST['str']); //удаляем все слешы $_POST['str'] = htmlspecialchars($_POST['str'],ENT_QUOTES);//преобразовывеем все html символы 2. Имена, фамилии города вот так Код (Text): $_POST['str']= (string) $_POST['str'];//Указываем тип $_POST['str']=addslashes($_POST['str']);//экранируем $_POST['str']=preg_replace ("/[^a-zа-я0-9А-ЯA-ZЧчСсТтьЬюЮЭэРрыЫФфъЪХхЩщШшЦцУу№\- ]/","",$_POST['str']); 3. Номера страниц вот так вот Код (Text): if (mb_strlen($_GET['n'], 'utf-8')>5) {$_GET['n']="0";} //Экранируем $_GET['n']=addslashes($_GET['n']); //Убираем все кроме цифр $_GET['n'] = preg_replace('~[^0-9]+~','',$_GET['n']); Правильно ли я все делаю? Извиняюсь за глупые вопросы =)
У вас сайт может работать с любыми базами данных или разработан под одну конкретную? Большинство пхп-расширений для доступа к БД имеют свои функции экранирования строк. Лучше использовать именно их, а не изобретать более медленные велосипеды. Это лишнее. Чем он ещё может быть? Это зачем? А если в тексте есть слэш? Он пропадёт. Фильтровать пользовательский ввод вообще считается дурной практикой. Пользовательские данные - священный грааль. Их нельзя менять. Проверить на корректность/некорректность - это всё, что можно с ними делать. Тут зависит от задачи. Если это запись в блог, то, скорее всего, пользователь захочет вставлять туда картинки, гиперссылки, видео с ютьюба и т.п. Так что всё гораздо сложнее.
ИМХО борьба с эскуэль инъекциями это как борьба за мир во всем мире. Структурированный и протестированный код не оставляет места никаким инъекциям. Добавлено спустя 39 секунд: Все эти эскуэль инъекшионз придумали маркетологи, чтобы бабла выбить.
Ну не совсем так. Все текстовые данные перед добавлением в запрос должны быть проэкранированы, просто потому что иначе какой-нибудь незлонамеренно введённый в данные апостроф может порушить запрос. Т.е. экранируем мы не для защиты от SQL-инъекций, по сути, а чтобы вполне легитимные пользовательские данные не нарушили синтаксис нашего запроса. В конце концов, не запрещать же пользователю регистрироваться, если его зовут д'Артаньян! А попутно мы как сладкую плюшку получаем и защиту от SQL-инъекций, поскольку если пользователь захочет назваться Код (Text): ' and 1=1; drop users; то это замечательное имя просто запишется в базу данных так, как оно введено, и пользователь даже сможет по нему залогиниться к нам. Ну если ему не лень вводить, нам тоже не жалко ))
Для нормального понимания темы рекомендую как минимум ознакомиться с данной лекцией: https://www.youtube.com/watch?v=Jxgq6eucWY4 Реально тема довольно большая и сложная, относиться к ней "авось пронесет" нельзя. Не хотите изучать вопрос - учимся работать с любым внятным фреймворком, который возьмет на себя все обработки переменных и подготовку запросов.
Для ленивых можно раскрыть суть вопроса Если я не забываю все строки прогонять через mysqli_real_escape_string, что может произойти? В случае простого поиска через LIKE ещё процент нужно экранировать, но это уже не безопасность, просто работать будет не так, как нужно.
В сферическом случае этого достаточно. На практике же вполне возможно, что вы это где-то забудете, поэтому рекомендуется использовать биндинг параметров - т.е. вы не напрямую вставляете значение параметра в запрос, а передаете обработчику шаблон запроса с метками параметров, и сами параметры в виде php-массива, а далее обработчик сам уже передает параметры в безопасном для обработки виде. Например, в случае использования adodb в качестве прослойки для работы с БД это будет выглядеть вот таким образом: Код (PHP): $bindVars = array('A','B','C'); $sql = "SELECT * FROM some_table WHERE col1=? AND col2=? AND col3=?"; $result = $db->execute($sql,$bindVars);
PDO. И, раз уж на то пошло, у меня ссылка даже в буфере осталась: http://php.ru/manual/pdo.prepared-statements.html
Подготовленные запросы удобны, когда нужно выполнить один и тот же запрос с разными параметрами. На практике, я не помню, чтобы хоть раз с таким столкнулся. В остальном, они мне не нравятся. Кода больше получается. Высчитывать эти знаки вопросов, когда нужно что-то изменить приятного мало. Легко ошибиться, что и в каком порядке вставляется в запрос. В PDO есть подгтовленные запросы с именованными параметрами, но всё равно удобства это не добавляет. Код не становится легче писать или легче читать. Если запрос не существует в целом виде, а генерируется из кусочков - это чистый геморрой. За это я ещё и ORM системы не люблю. Их только через eval прогонять, когда ты не знаешь, какой у тебя будет запрос.