Правда ли, что хранимые процедуры предотвращают атаки SQL-инъекций на базы данных PostgreSQL? Я провел небольшое исследование и выяснил, что SQL Server, Oracle и MySQL не защищены от внедрения SQL, даже если мы используем только хранимые процедуры. Однако эта проблема не существует в PostgreSQL.
Предотвращает ли реализация хранимых процедур в ядре PostgreSQL атаки SQL-инъекций или это что-то еще? Или PostgreSQL также подвержен внедрению SQL, даже если мы используем только хранимые процедуры? Если да, пожалуйста, покажите мне пример (например, книга, сайт, бумага и т. Д.).
postgresql
security
sql-injection
Am1rr3zA
источник
источник
Ответы:
Нет, хранимые процедуры не предотвращают внедрение SQL. Вот фактический пример (из собственного приложения, созданного мной, где я работаю) хранимой процедуры, которая, к сожалению, допускает внедрение SQL:
Этот код сервера SQL:
примерно эквивалентно postgres:
Идея разработчика состояла в том, чтобы создать универсальную процедуру поиска, но в результате предложение WHERE может содержать все, что хочет пользователь, что позволяет посещать маленькие таблицы Бобби .
Используете ли вы операторы SQL или хранимую процедуру, не имеет значения. Важно то, использует ли ваш SQL параметры или конкатенированные строки. Параметры предотвращают внедрение SQL; объединенные строки позволяют SQL-инъекцию.
источник
Атаки SQL-инъекцией - это атаки, в которых ненадежный ввод представляет собой непосредственно добавленные запросы, что позволяет пользователю эффективно выполнять произвольный код, как показано в этом каноническом комиксе XKCD.
Таким образом, мы получаем ситуацию:
Хранимые процедуры, как правило, являются хорошей защитой от атак внедрения SQL, поскольку входящие параметры никогда не анализируются.
В хранимой процедуре, в большинстве БД (и программ, не забывайте, что предварительно скомпилированные запросы считаются хранимыми процедурами) выглядят следующим образом:
Затем, когда программа желает получить доступ, она вызывает
foo(userInput)
и счастливо получает результат.Хранимая процедура не является волшебной защитой от SQL-инъекций, поскольку люди вполне могут писать плохие хранимые процедуры. Тем не менее, предварительно скомпилированные запросы, хранящиеся ли они в базе данных или в программе, намного труднее открыть дыры в безопасности, если вы понимаете, как работает SQL-инъекция.
Вы можете прочитать больше о SQL-инъекции:
источник
Да, в некоторой степени.
Хранимые процедуры сами по себе не помешают внедрению SQL.
Позвольте мне сначала процитировать SQL-инъекцию из OWASP
Вы должны санировать вводимые пользователем данные и не объединять операторы SQL, даже если вы используете хранимую процедуру.
Джефф Эттвуд объяснил последствия объединения SQL в « Дайте мне параметризованный SQL, или дайте мне смерть »
Ниже приводится интересный мультфильм, который мне приходит в голову всякий раз, когда я слышу SQL-инъекцию. Думаю, вы поняли :-)
Взгляните на Шпаргалку по предотвращению инъекций SQL , методы предотвращения которых четко объяснены ...
источник
Конкатенация строк является причиной внедрения SQL. Этого можно избежать, используя параметризацию.
Хранимые процедуры добавляют дополнительный уровень безопасности, применяя неверный синтаксис при объединении, но не являются «более безопасными», если в них используется, скажем, динамический SQL.
Итак, ваш код выше вызван объединением этих строк
exec sp_GetUser '
x' AND 1=(SELECT COUNT(*) FROM Client); --
' , '
monkey
'
Это дает неверный синтаксис, к счастью
Параметризация это дало бы
Это означает
@UserName
знак равноx' AND 1=(SELECT COUNT(*) FROM Client); --
@Password
знак равноmonkey
Теперь в приведенном выше коде вы не получите строк, потому что я предполагаю, что у вас нет пользователя
x' AND 1=(SELECT COUNT(*) FROM Client); --
Если хранимый процесс выглядел следующим образом (с использованием сцепленного динамического SQL ), то ваш параметризованный хранимый вызов proc все еще разрешит SQL-инъекцию
Итак, как показано, конкатенация строк является главным врагом для внедрения SQL
Хранимые процедуры добавляют инкапсуляцию, обработку транзакций, ограниченные разрешения и т. Д., Но их все еще можно использовать для внедрения SQL.
Вы можете посмотреть на переполнение стека для получения дополнительной информации о параметризации
источник
«Атака инъекции SQL происходит , когда пользовательский ввод неправильно закодирован. Как правило, ввод данных пользователя некоторые данные пользователя отправляемые с ее запросом, то есть значения в
$_GET
,$_POST
,$_COOKIE
,$_REQUEST
или$_SERVER
массивы. Однако, пользовательский ввод могут также поступать из множества других источники, такие как сокеты, удаленные веб-сайты, файлы и т. д. Поэтому вы должны действительно рассматривать все, кроме констант (например'foobar'
), как ввод данных пользователем ".Недавно я тщательно изучал эту тему и хотел бы поделиться с другими довольно интересным материалом, чтобы сделать этот пост более полным и поучительным для всех.
С YouTube
Из Википедии
От OWASP
Из руководства по PHP
От Microsoft и Oracle
Переполнение стека
Сканер SQL-инъекций
источник
Хранимые процедуры магическим образом не предотвращают внедрение SQL, но они значительно упрощают его предотвращение. Все, что вам нужно сделать, это что-то вроде следующего (пример Postgres):
Это оно! Проблема возникает только при формировании запроса с помощью конкатенации строк (например, динамический SQL), и даже в этих случаях вы можете связать! (Зависит от базы данных.)
Как избежать внедрения SQL в ваш динамический запрос:
Шаг 1) Спросите себя, действительно ли вам нужен динамический запрос. Если вы соединяете строки только для того, чтобы установить ввод, то вы, вероятно, делаете это неправильно. (Из этого правила есть исключения - одно исключение относится к отчетам о запросах в некоторых базах данных. У вас могут быть проблемы с производительностью, если вы не заставляете его скомпилировать новый запрос при каждом выполнении. Но изучите эту проблему, прежде чем переходить к этому. )
Шаг 2) Изучите правильный способ установки переменной для вашей конкретной СУБД. Например, Oracle позволяет вам делать следующее (цитируя их документы):
Здесь вы все еще не объединяете входные данные. Вы в безопасности! Ура!
Если ваша база данных не поддерживает что-то подобное выше (надеюсь, что ни один из них все еще не настолько плох, но я не удивлюсь) - или если вам все еще действительно нужно объединить свои данные (как в «иногда» случае представления запросов как Я намекал выше), тогда вы должны использовать правильную функцию выхода. Не пиши это сам. Например, postgres предоставляет функцию quote_literal (). Таким образом, вы бы запустить:
Таким образом, если in_name является чем-то коварным, как '[snip] или 1 = 1' (часть "или 1 = 1" означает выбрать все строки, позволяя пользователю видеть зарплаты, которые он не должен!), То quote_literal сохраняет ваш зад сделать результирующую строку:
Результаты не будут найдены (если у вас нет сотрудников с действительно странными именами.)
В этом суть! Теперь позвольте мне оставить вам ссылку на классическую статью гуру Oracle Тома Кайта на тему SQL-инъекций, чтобы понять суть : Linky
источник
quote_ident()
- но в целом самый простой способ написания динамического SQL, защищенного от инъекций, - это использоватьformat()
и использовать заполнители%I
для идентификаторов и%L
литералов. Таким образом, SQL намного более читабелен, чем эквивалентная версия, использующая функции||
иquote_....()
функции