Форматирование строк с SQL запросами

За окном уже скоро 2016-й год, а даже в очень больших компаниях некоторые программисты умудряются форматировать строки для SQL запросов. Блять, ну пора бы уже понять, что SQL Injection - это не шутки. Ну ладно молодые программисты делают такие ошибки. Ну ладно в небольших компаниях. Но в крупной солидной консалтинговой конторе написать Format, за такое я бы уволил. Или зарплату снизил до $5 в час, как интерну. Потому что больше такая работа не стоит. 

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


Комментарии

Алексей

Я посчитал свою в переводе на доллары и у меня получилось чуть более 3, так что 5 еще круто :-)

Николай

А можно пример опасности? Во времена параметризации запросов тяжело представить уязвимый сценарий

Михаил Фленов

Форматировать строку - имелось ввиду без параметризации. При использовании параметров уязвимости не будет.

Alouette

Михаил, можете пояснить? Не совсем понял, что вы имеете в виду под форматированием. Приведение к стилю кодирования? Тогда SQL-инъекции не при чем. Использование функции Format? А на каком языке? В SQL, насколько мне известно, нет такой инструкции. Может быть, имеется в виду конструкция вроде String.Format("SELECT * FROM 123 WHERE id={1}", id) из C#? Но разве запросы должны храниться не на сервере в виде хранимых процедур? И разве в современных системах их исполнение осуществляется не посредством фреймворков?

Михаил Флёнов

1. Как раз String.Format и имеется ввиду.
2. Я уже не помню, чтобы кто-то рекомендовал использовать процедуры. По крайней мере я никогда этого не рекомендовал и не буду
3. На сколько я помню, этот пункт противоречит предыдущему. Фреймворки типа doctrine в PHP или LINQ в .NET как раз генерят SQL запросы, а не процедуры. И я уже много раз говорил, что против использования этих фреймворков.

Кстати, в коде, о котором я говорю был фреймворк, который поддерживал параметризированные запросы. Но почему-то вместо передачи параметров, программисты решили использовать форматирование String.Format

Евгений

Все рано не понятно. Хотелось бы конкретный пример. Неужели в запросе String.Format("SELECT * FROM 123 WHERE id={1}", id), если id="delete from tbPerson", обнулится вся таблица tbPerson? Каким образом, подобные уязвимости могут быть использованы? Да мы скорее от сервера получим ответ от некорректной sql-инструкции. Или речь идет о различных "самодельных", бесплатных sql-серверах?

Михаил Флёнов

Подробные примеры я описывал в PHP глазами хакера и Web Сервер глазами хакера. Из базы данных можно будет удалить все строки, если id="1;delete from tbPerson"

Николай

Просто любопытно, а что не так с теми фрейморками, что ты против их использования?

Михаил Фленов

Люблю иметь полный контроль и не иметь дополнительной прослойки, которая на мой взгляд не добавляет удобства, а добавляет гемора. Это личное предпочтение и никому не навязываю. Я не против, если кто-то другой использует.

Кстати, на PHP я вообще-то использую doctrine. Не сказал бы, что я прям вообще в восторге от него, но приемлемо. Наверно первая прослойка, которая мне понравилась.

знающий

Михаил, а чем хранимые процедуры не угодили? Особенно компилируемые в нативный код SQL server 2016

darthat

Может там проверка какая-нибудь делается для параметра, типа tryParse(...)? Нельзя же тупо подставлять в SQL запрос любую хрень, которую отправит пользователь, это всем понятно.

Михаил Фленов

0 гибкости, больше гемора, чем преимущества.

Евгений

А если String.Format("SELECT * FROM 123 WHERE id={1}", id) заменить на String.Format("SELECT * FROM 123 WHERE id='{1}'", id), то при id="1;delete from tbPerson" сервер вернет ошибку, но правда тип столбца id таблицы [123] должен быть GUID, а не int. В потенциально опасном коде имеется возможность выполнить 2 и более операторов sql. Просто надо за этим следить, когда запрос "собираем" из отдельных строк. Например, проверкой наличия операторов модификации данных (insert, delete, update, drop и пр.) в переменной строки запроса, если осуществляется выборка. В более сложных случаях составлять регулярные выражения, т.к. этот метод построения sql-запросов все же гибче. Потому то его и используют до сих пор.

Михаил Фленов

Ни в коем случае ненужно низачем следить. Используйте параметризированные запросы и будет все отлично.

Radekk

LINQ
линк вроде еще до 11% доп нагрузки на процессор дает, что тоже не есть гуд.

Шкрыль Андрей aka Li

Михаил очень откровенная строка))) особенно понравилась фраза "Блять, ну пора бы уже понять,", мне кажется что если человек выбрал профессию не ту, которую он любит, то он всегда будет писать программы абы как, а потом, когда дело дойдет до ответственности, такие псевдо специалисты превращаются в маленьких детей, и говорят, что это не их ответственность, это как бы случайно, к сожалению в России таких более 90%)) Поэтому на западе, машины работают на людей, а в России люди попадают в заложники к машинам, хорошо что появилась Java,там девиз написано один раз работает везде))


Добавить Комментарий

О блоге

Программист, автор нескольких книг серии глазами хакера и просто блогер. Интересуюсь безопасностью, хотя хакером себя не считаю

Обратная связь

Без проблем вступаю в неразборчивые разговоры по e-mail. Стараюсь отвечать на письма всех читателей вне зависимости от страны проживания, вероисповидания на русском или английском языке.

Пишите мне