Является ли зависимость от параметризованных запросов единственным способом защиты от внедрения SQL?

13

Все, что я видел в атаках с использованием SQL-инъекций, показывает, что параметризованные запросы, особенно хранимые процедуры, являются единственным способом защиты от таких атак. Пока я работал (еще в темные века), хранимые процедуры считались плохой практикой, главным образом потому, что их считали менее обслуживаемыми; менее проверяемый; сильно связанный; и заблокировал систему в одном поставщике; ( этот вопрос охватывает некоторые другие причины).

Хотя, когда я работал, проекты практически не знали о возможности таких атак; Были приняты различные правила для защиты базы данных от разного рода коррупции. Эти правила могут быть обобщены как:

  1. Ни один клиент / приложение не имеет прямого доступа к таблицам базы данных.
  2. Все обращения ко всем таблицам осуществлялись через представления (а все обновления базовых таблиц выполнялись с помощью триггеров).
  3. У всех элементов данных был указан домен.
  4. Ни один элемент данных не мог быть обнуляемым - это имело значение, что администраторы базы данных иногда стискивали зубы; но был исполнен.
  5. Роли и разрешения были установлены соответствующим образом - например, ограниченная роль, которая дает только представлениям право изменять данные.

Так является ли набор (принудительных) правил, таких как этот (хотя и не обязательно этот конкретный набор), подходящей альтернативой параметризованным запросам для предотвращения атак внедрения SQL-кода? Если нет, то почему нет? Можно ли защитить базу данных от таких атак с помощью конкретных (только) мер?

РЕДАКТИРОВАТЬ

Акцент на вопрос изменился незначительно, в свете первых полученных ответов. Базовый вопрос без изменений.

EDIT2

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

Подход, подразумеваемый в моем вопросе, был основан на «защите» базы данных, и я понятия не имел, является ли это жизнеспособным вариантом. Дальнейшие исследования показали, что существуют такие подходы. Я нашел следующие источники, которые обеспечивают некоторые указатели на этот тип подхода:

http://database-programmer.blogspot.com

http://thehelsinkideclaration.blogspot.com

Принципиальные особенности, которые я взял из этих источников:

  1. Обширный словарь данных в сочетании с обширным словарем данных безопасности
  2. Генерация триггеров, запросов и ограничений из словаря данных
  3. Минимизируйте код и максимизируйте данные

Хотя ответы, которые я получил до сих пор, очень полезны и указывают на трудности, возникающие из-за игнорирования параматеризованных запросов, в конечном итоге они не отвечают на мои первоначальные вопросы (теперь выделены жирным шрифтом).

Крис Уолтон
источник
Я не покупаю аргументы против хранимых процедур. Они просто не соответствуют действительности.
Конрад Рудольф
Что случилось с требованием отсутствия нулей?
Марк Канлас
2
@Konrad Rudolph - Если вы пишете свое приложение на MySQL, а затем решаете перейти на DB2, думаете ли вы, что хранимые процедуры будут совместимы? Точно так же, если вы хотите перейти на SQLLite? Кроме того, предположим, что вы обновляете свою ОС - если ваши хранимые процедуры скомпилированы в C (который они есть в DB2), им, вероятно, потребуется перекомпиляция. Это разумные аргументы - не абсолютные, а разумные.
Мэтью Флинн
@ Мэтью Дух. Я действительно думал о «параметризованных запросах», когда читал это и комментировал это. Хранимая процедура = целая другая история.
Конрад Рудольф

Ответы:

25

Сохраненные процедуры не защищают автоматически от инъекций. Что насчет этого

CREATE PROC proc
  @id VARCHAR(5)
AS
BEGIN
  EXEC("SELECT * FROM Client WHERE ClientId = " + @id);
END

Использование параметризованных запросов защитит вас от внедрения, независимо от того, находятся ли они в процессах или нет.

Craig
источник
Спасибо за внимание к параметризованным запросам, а не к процессам. Тем не менее, я спрашиваю, может ли база данных быть защищена с помощью методов, отличных от таких запросов - в частности, методов, которые ограничены только уровнем базы данных.
Крис Уолтон
1
+1 В дополнение к этому я хотел бы заявить, что хранимые процедуры в основном считаются безопасными, поскольку это единственный способ запретить пользователям прямой доступ к таблицам, при этом сохраняя способ извлечения данных. Это единственный способ обеспечить права на основе строк и столбцов, когда пользователю требуется прямой доступ к базе данных со своим клиентом без каких-либо промежуточных действий.
Сокол
2
@ Крис - я думаю, что Крэйг говорит здесь о том, что вы не можете предположить, что прок на самом деле вас защищают. Возможно, это не полный ответ, а скорее исправление предположения в названии.
Джон Хопкинс
@Jon - Я изменил название вопроса и внес некоторые изменения в вопрос в свете исправления Крейга. Я не знал о предположении, которое я сделал в вопросе, пока я не начал получать ответы.
Крис Уолтон
2
Чтобы подкрепить то, что Крэйг пишет выше, см. Databasesecurity.com/dbsec/part-sql-injection.pdf , «Латеральная инъекция SQL: новый класс уязвимостей в Oracle»
Брюс Эдигер,
11

Так является ли набор (принудительных) правил, таких как эта, подходящей альтернативой хранимым процедурам для предотвращения атак с использованием SQL-инъекций? Если нет, то почему нет?

Нет, потому что они наносят довольно большой штраф разработчикам. Разбивка по элементам:

1. Ни один клиент / приложение не имели прямого доступа к таблицам базы данных.

Используйте роли. Клиенты должны иметь возможность доступа к БД только через ограниченную роль, которая имеет только SELECT, INSERT, UPDATE и DELETE доступ к тем таблицам (и строкам, где это возможно), к которым ей необходим доступ. Если вы хотите убедиться, что ни один клиент не может спамить или удалить все записи, используйте API для изменения данных.

2. Все обращения ко всем таблицам были через представления.

Это может быть что угодно от незначительного до огромных затрат производительности, в зависимости от эффективности представлений. Это ненужная сложность, которая замедляет разработку. Используйте роли.

3. У всех элементов данных был указан домен.

Может быть много работы для поддержки, и, вероятно, должны быть сведены в отдельную таблицу.

4. Ни одному элементу данных не разрешалось обнуляться - это имело последствия, когда администраторы базы данных иногда стискивали зубы; но был исполнен.

Это просто неправильно. Если разработчики не могут справиться NULLс этим, у вас большие проблемы.

Можно ли защитить базу данных от таких атак с помощью конкретных (только) мер?

Вам не нужны хранимые процедуры, просто используйте параметризованные запросы с функцией, которая экранирует аргументы, например pg_query_params . Конечно, если ваша база данных доступна для записи во всем мире или у роли клиента есть полный доступ ко всему, вы все равно облажались. Кто-то просто должен прийти и понять, что делает клиент, а затем за пять минут приготовить клиента, который уничтожит (или, что еще хуже, отравит) вашу БД.

l0b0
источник
1
Домен: en.wikipedia.org/wiki/Data_domain
Дэн МакГрат
+1 за роли. Они вносят основной вклад в это - я не включил роли в свой вопрос, но они были частью установки - в частности, представлениям была назначена ограниченная роль, которую вы предлагаете для клиентов. Точка взята на производительность хит просмотров. Домены включали валидационные тесты - диапазоны и длина в основном. Ваши комментарии к правилу обнуляемости данных гораздо более вежливы, чем некоторые, которые я слышал об этом правиле. Я не указал явно, что разрешения будут установлены соответствующим образом, хотя это было мое предположение.
Крис Уолтон
6

Я не уверен, что ваши правила защищают вас полностью.

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

Во-вторых, я читаю их так: правила, подобные этим, могут усложнить использование, но они не мешают этому. Например, отсутствие прямого доступа к таблицам на самом деле не сильно изменится, если представления позволяют вам получить доступ к одним и тем же данным. Если клиент должен сделать что-то, представление должно облегчить это, и если представление облегчает это, те же самые функции / данные могут быть использованы злоумышленником.

Помните также, что речь идет не только об обновлении или удалении данных. Частью уязвимости, связанной с внедрением SQL, является сбор информации, и для этого вас не волнует, были ли данные переданы обратно через представление vCustomers или базовую таблицу Customers. Вы можете защитили себя от некоторых слабых сторон , но не все. Точно так же, если обновления могут быть сделаны клиентом, даже если через триггеры, тогда SQL может быть написан для запуска триггеров и выполнения обновлений.

(В отношении всех обновлений, выполняемых с помощью триггеров, я скажу две вещи: (1) когда я прочитал это, у меня во рту стало немного плохо, и (б) вам не нравятся хранимые процедуры, потому что они ' «менее ремонтопригоден; менее тестируем; сильно связан; и система привязана к одному поставщику», но вы используете триггеры, о которых можно сказать то же самое.)

Все, что вам нужно, это одна дыра, которая позволяет выполнять операторы SQL (и я не вижу ни одного из этих правил, препятствующих этому), и злоумышленник находится внутри. Они могут находить за собой очень неинтуитивную базу данных, но если они решат, что это только замедляйте их, а не останавливайте).

Другое дело, что вы также добавляете сложность и (а также накладные расходы, которые создают) сложность имеет тенденцию приводить к дырам, которые можно использовать.

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

Джон Хопкинс
источник
+1 за понимание моего фактического запроса в свете моих неявных, неосознанных предположений и за ответ на него соответствующим образом. Что касается того, почему кто-то может беспокоиться - я работаю над проектом, в котором большая часть кода будет сгенерирована из соответствующего описания архитектуры - и часть этой архитектуры описывает, как генерировать процедуры доступа к базе данных. До сих пор неясно, какую форму примут эти сгенерированные процедуры.
Крис Уолтон