Как предотвратить Sql-инъекции в пользовательских Sql-запросах - PullRequest
4 голосов
/ 14 января 2009

У меня есть проект (частный, веб-сайт ASP.net, защищенный паролем с помощью https), в котором одно из требований заключается в том, чтобы пользователь мог вводить запросы Sql, которые будут напрямую запрашивать базу данных. Мне нужно иметь возможность разрешать эти запросы, не допуская, чтобы они наносили ущерб самой базе данных, а также не могли получить доступ или обновить данные, к которым они не смогут получить доступ / обновить.

Я разработал следующие правила для реализации:

  1. Используйте пользователя базы данных, который только имеет разрешение на выбор таблицы / просмотр и обновление таблицы (таким образом, любые другие команды, такие как drop / alter / truncate / insert / delete, просто не будут выполняться).
  2. Убедитесь, что выписка начинается со слов «Выбрать» или «Обновить»
  3. Убедитесь (используя Regex), что в выражении нет точек с запятой, которые не заключены в одинарные кавычки, пробелы и буквы. (Здесь мысль состоит в том, что единственный способ, которым они могут включить второй запрос, состоит в том, чтобы завершить первый точкой с запятой, которая не является частью входной строки).
  4. Убедитесь (используя Regex), что у пользователя есть разрешение на доступ к запрашиваемым / обновляемым таблицам, включенным в объединения и т. Д. Это включает любые подзапросы. (Частично способ, которым это будет достигнуто, состоит в том, что пользователь будет использовать набор имен таблиц, которые на самом деле не существуют в базе данных, часть синтаксического анализа запроса будет заключаться в замене в запросе правильных соответствующих имен таблиц) .

Я что-то упустил?

Цель состоит в том, чтобы пользователи могли запрашивать / обновлять таблицы, к которым у них есть доступ, любым способом, который они считают нужным, и предотвращать любые случайные или злонамеренные попытки повредить базу данных. (А поскольку требуется, чтобы пользователь генерировал sql, у меня нет возможности параметризовать запрос или санировать его с помощью любых известных мне встроенных инструментов).

Ответы [ 15 ]

0 голосов
/ 15 января 2013

Множество ответов говорят, что это плохая идея, но иногда на этом настаивают требования. Есть одна ошибка, которую я не заметил, упомянутый в предложениях «Если вам все равно придется это делать»: Убедитесь, что все операторы обновления включают в себя предложение WHERE. Это слишком легко запустить

UPDATE ImportantTable
SET VitalColumn = NULL

и упустить важное

WHERE UserID = @USER_NAME

Если обновление требуется по всей таблице, тогда достаточно просто добавить

WHERE 1 = 1

Требование предложения where не останавливает злонамеренного пользователя от совершения плохих действий, но должно уменьшить случайные изменения всей таблицы.

0 голосов
/ 14 января 2009

вот еще один пример

хакеру не нужно знать настоящее имя таблицы, он / она может запускать недокументированные процедуры, подобные этой

sp_msforeachtable 'print ''?''' 

просто вместо печати будет сбрасываться

0 голосов
/ 14 января 2009

Хотя я согласен с Джоэлом Коохорном и SQLMenace, у некоторых из нас есть «требования». Вместо того чтобы заставлять их отправлять специальные запросы, почему бы не создать визуальный построитель запросов, подобный тем, которые можно найти в примерах приложений MS, найденных на asp.net, или попробовать эту ссылку .

Я не против замечаний Джоэла. Он прав. Наличие пользователей (помните, что мы здесь говорим с пользователями, им может быть наплевать на то, что вы хотите применить), создает запросы как приложение без «уровня бизнес-логики», не говоря уже о дополнительных вопросах, на которые нужно отвечать, если определенные результаты не совпадают другие вспомогательные результаты приложения.

0 голосов
/ 14 января 2009

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

Ответ выше моего тоже очень хороший.

0 голосов
/ 14 января 2009

Если им не нужно выполнять действительно сложные запросы, вы можете предоставить пользовательский интерфейс, который допускает только определенные варианты, например выпадающий список с «обновить, удалить, выбрать», после чего следующий ddl автоматически заполнится списком доступных таблицы и т. д. аналогичны построителю запросов в студии управления sql.

Затем в коде на стороне сервера вы преобразуете эти группы элементов пользовательского интерфейса в операторы SQL и используете параметризованный запрос для остановки вредоносного контента

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...