Comments 30
Интересно вы собираете свой накопленный опыт копипастом библиотечной документации https://libpqxx.readthedocs.io/en/6.4/a01477.html
prepared statement?
самый правильный ответ (туда же доступ к БД только через хранимки с фиксированными параметрами), но не молодежно, не модно. Это ж надо в SQL таки разобраться, а никто не хочет ;)
"Хранимки" тупо неудобны в поддержке. Да, надо разбираться. А еще накатывать миграцию каждый раз, когда в запросе поменяется одно слово. И при этом непонятно — зачем, если параметризованный запрос и так решает проблему.
зависит от задачи, размера системы, критичности данных и т.п.. Хранимки и VIEW - по сути рализуют инкапсуляцию данных от пользователя и предоставляют унифицированный интерфейс работы с данными. В общем реализуют те же концепции деления зон ответственности, что и ООП\модули.
Ну вот и надо использовать ООП и модули.
Заставлять программиста постоянно писать код на этом недоязыке будет только садист.
Я понимаю, когда действительно есть причина использовать процедуру, для обработки большого массива данных на стороне БД например. Но писать КАЖДЫЙ запрос через процедуру- это уже что-то нечеловеческое.
Возможно, в каких-то легаси системах, где пользователей тысячи, это и может быть оправдано. В большинстве же современных приложений, где пользователей у БД один-два, то кого-то от чего-то изолировать — это просто наживать себе геморрой на пустом месте.
Эээ… и кстати. Эти соображения в любом случае не имеют отношения к исходной теме поста. Собственно, вызов процедуры из кода тоже надо минимально защищать. Понятно, что там пространство для манёвра меньше, но если API позволяет выполнение больше одного запроса за раз, то здравствуй мальчик Bobby Tables! И в итоге получается двойная работа — сначала пишем процедуру, чтобы защитить запрос от инъекции, а потом вызываем её в приложении, и уже этот вызов тоже защищаем от инъекции.
просто я сужу из опыта банковских core db, где пользователей действительно тысячи и они очень разные от юзеров до внешних систем. И тут полагаться что абсолютно везде снаружи будет сделано как надо - утопично.
Здравствуйте,
Я автор исходной статьи.
Спасибо за напоминание, в своем коде мы в основном используем raw запросы, но prepared statement конечно также является средством против SQL инъекций
Даже без prepared statement, просто используйте параметризированные запросы.
Сложнее когда запрос динамический, но даже это решаемо.
Априори, если зачем-то нужно следить вручную, рано или поздно упустите это.
В процессе своей работы мы с коллегами уделяем большое внимание вопросам безопасности наших приложений. SQL-инъекция — одна из самых серьезных угроз этой безопасности
Капец. Десять-двадцать лет спустя, когда эскейп функции уже интегрированы штатно практически в любой язык/фреймворк, в вашем продукте это до сих пор одна из самых серьезных угроз безопасности? Может нужно просто почитать документацию, как сейчас оформляют запросы в базу?
Сарказм конечно, но статья - слишком школьный уровень
Здравствуйте,
Я автор исходной статьи.
К сожалению согласно недавнему отчету MITRE SQL инъекции стоят на третьем месте среди 25 самых опасных проблем в программном обеспечении за последние два года. Подробнее можете посмотреть тут https://cwe.mitre.org/top25/
А биндинг параметров разве не устраняет проблему SQL-инъекций в принципе?
Ну формально ещё могут быть идентификаторы и ключевые слова, защита которых тоже упоминается. Но биндинг мог бы сделать эту статью значительно короче, и превратить её из ассорти дублирующихся и противоречивых советов в простую инструкцию: данные биндим, остальное фильтруем через белые списки.
Здравствуйте,
Я автор исходной статьи.
Если Вы имеете в виду prepared statement то уже ответили выше
Мда, согласен с предыдущими комментаторами.
Статья — просто коллекция заблуждений и "вредных советов".
Например, прямо сходу получаем утверждение, которое содержит сразу два заблуждения, и верно только в одном — в том, что очень многие разработчики действительно их разделяют:
многие из вас знают, что валидирование пользовательского ввода — краеугольный камень процесса безопасной разработки
… и только немногие понимают, что валидирование пользовательского ввода не имеет ни малейшего отношения к безопасности. Потому что во-первых, валидирование относится к бизнес-логике, а не к безопасности. А во-вторых, здесь вводится чрезвычайно вредное понятие источника данных. И фокусируясь на "пользовательском" вводе разработчик пропускает инъекцию во всех остальных. Казалось бы — какой смысл вообще упоминать источник данных? Какая разница, от пользователя пришли данные, или или нашей БД? Зачем вообще вводить такой параметр? Ведь код будет банально проще, если в нем будет унифицированная обработка данных, независимо от того, "пользовательские" они, или нет.
Любые элементы, которые добавляются в запрос динамически, разделяются только на две категории: данные и все остальные элементы. Данные добавляются через параметры, а любые другие элементы через белый список. Всю статью можно свести к этим двум простым правилам.
И получится не только проще, но и безопаснее. Без возможности пропустить инъекцию второго порядка и без дурацких идей, что "если список в HTML форме формируется на сервере, то это, наверное, не пользовательский ввод"
Экранирование строки
Формально здесь всё верно.
Но дьявол в деталях. Многие поколения программистов выросли с убеждением, что экранирование защищает от инъекций. И как результат написали тонны уязвимого кода.
Любое упоминание экранирования должно всегда писать большими буквами, что работает оно только для SQL строк. А числам или идентификаторам оно поможет как мёртвому припарки. Именно большими буквами. Простого упоминания недостаточно. Оно проходит мимо ушей. И экранирование воспринимается просто как волшебная защита любых элементов запроса.
И ещё мелкое замечание. Я не знаю, что вы понимаете под словами "символы разрыва строк", но русскоязычный читатель скорее поймет это как символы перевода строки. И удивится — при чем здесь инъекции.
quote_name
не защищает от инъекции, когда атакующий передаст валидное имя поля, но такое, которое ему не разрешено менять. Поэтому квотить идентификаторы надо, просто чтобы не нарваться на ключевое слово, но проверять их всё равно по белому списку. То есть в контексте защиты quote_name не должна упоминаться
Уменьшение угрозы SQL-инъекций
Меня всегда умиляет наличие этого раздела в подобных статьях. Как, собственно, и сам термин "митигация". Инъекции надо предотвращать, полностью. А не "уменьшать угрозу", подразумевая, что она остаётся.
Тем более, что в этом разделе свалено всё в кучу — и паллиатив с "чистотой типов", который является скорее вредным советом, не имеющим отношения к защите от инъекций, и настоящая защита через белые списки.
Здравствуйте,
Я автор исходной статьи.
Мы в своей работе пользуемся принципами безопасной разработки, такими например как Input Validation (https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html) и Defence in Depth(https://en.wikipedia.org/wiki/Defense_in_depth_(computing)). Может быть фраза "пользовательские данные" была выбрана неудачно, но принципы безопасной разработки требуют валидировать все данные, чему мы и следуем.
Полностью с Вами соглашаемся с утверждением про "две категории: данные и все остальные элементы". Мы же даем в статье обзор имеющихся средств pqxx по защите от SQL инъекций, это может быть полезно, если скажем у Вас есть легаси код, в который нужно встроить защиту от SQL инъекций, но Вы не готовы переписать все запросы с использованием параметров.
По поводу "Многие поколения программистов выросли с убеждением, что экранирование защищает от инъекций. И как результат написали тонны уязвимого кода." нельзя с этим не согласится, спасибо за уточнение. Под символами разрыва строк в статье понимаются одинарные кавычки '
То что quote_name не защищает от инъекции когда атакующий передаст валидное имя поля даже не обсуждается потому что так оно и есть. Для защиты в таких случаях как раз и используется input validation, такие, как белые списки например.
Вы заявляете что "Инъекции надо предотвращать, полностью". Полностью с Вами в этом согласны. Но продукты без ошибок и без уязвимостей это скорее абстрактный идеал к которому все стремятся, но который так и остается недостижимым. В достаточно большом продукте никто не даст Вам 100% гарантию, что продукт не имеет уязвимостей. Скорее даже наоборот: утверждения что какой-то продукт не имеет уязвимостей вообще или что какой-то продукт информационной безопасности выявит у Вас все уязвимости вызывают опасения в компетенции тех кто делает такие заявления. Предотвращение уязвимостей в продукте это по нашему мнению скорее компромисс между новой функциональностью, сроками, затратами на разработку и требованиями по безопасности продукта.
Да дело ведь не в том, согласны вы, или нет. А в том, что статья получилась бессистемной и поэтому только запутывает читателя. У вас нигде в статье не написано, что она описывает ваш исключительный кейс с кучей легаси. В итоге получился винегрет, из которого совершенно непонятно, какой метод применять в каком конкретном случае.
Предотвращение уязвимостей в продукте это по нашему мнению скорее компромисс между новой функциональностью, сроками, затратами на разработку и требованиями по безопасности продукта.
Вот видите, вы сами же и соглашаетесь с тем, ваша статья выставляет элементарные рекомендации по защите от инъекций в виде каких-то путанных решений, которые затрудняют(?!) разработку.
Митигация
Извините, но это слово зучит как болезнь какая-то... Вы бы лучше по-русски написали, было бы понятнее всем - "предотвращение".
Прочитал почувствовал себя в 2007, спасибо.
> Наверняка многие из вас знают, что валидирование пользовательского ввода — краеугольный камень процесса безопасной разработки.
это как раз примерно тогда и забылось.
Что должна содержать в себе статья о защите от SQL инъекций в 2023 году?
только одну строку "Для защиты от SQL инъекций разделяйте запрос и параметры."
Что это значит что нельзя делать "SELECT * FROM my_table WHERE name = '"+name+ "''
А следует делать "SELECT * FROM my_table WHERE name = $1" и параметр передавать при вызове
Вопрос из любопытства, а были случаи, когда вы давали комментарии автору, он дорабатывал статью и материал становился годным?
Вообще, это рабочая схема? Дорабатывать статьи?
В целом да, но для Хабра скорее нет.
Во-первых, статья уже заминусована, и никакого стимула её исправлять нет, голоса назад не вернешь.
Во-вторых, это статья в корпоративном блоге. То есть разработчик из-под палки написал статью, на тему, которая ему неинтересна, пособирав материал в интернете. При этом само содержание статьи заказчика — отдел маркетинга — не волнует.
PostgreSql старая Сишная история но со своими приколами, хоть эта база или как она используется в линуксе СУБД использует некие ограничения, на практике они почти не влияют, плюсом в последними версии добавили поддержку многих языков по типу питона, перла, дало новый виток жизни
Впринцпе описано всё на доступном языке, даже для чайников, но всё еще не понятно, зачем уменьшать угрозу, если ее просто надо устранить? если автор поправит это, то будет не плохая статья для начинаний, но не средний уровень
Митигация SQL-инъекций при работе с PostgreSQL