Написание защищенного динамического SQL-кода в SQL Server (ADO.NET)
Обновлен: November 2007
Внедрение кода SQL — это процесс, посредством которого пользователь-злоумышленник вводит инструкции языка Transact-SQL вместо допустимых входных данных. Если входные данные передаются непосредственно на сервер без проверки, и если в приложении не приняты меры против выполнения внедренного кода, то появляется возможность осуществлять злонамеренные действия для повреждения или уничтожения данных.
Любая процедура, создающая инструкции SQL, должна рассматриваться на предмет уязвимости к внедрению небезопасного кода, поскольку SQL Server выполняет все получаемые синтаксически правильные запросы. Даже параметризованные данные могут стать предметом манипуляций опытного и решительного злоумышленника. В случае применения динамического кода SQL следует обязательно параметризовать применяемые команды и никогда не включать значения параметров непосредственно в строку запроса.
Принцип осуществления атаки путем внедрения кода SQL
Атака осуществляется посредством преждевременного завершения текстовой строки и присоединения к ней новой команды. Поскольку к вставленной команде перед выполнением могут быть добавлены дополнительные строки, злоумышленник заканчивает внедряемую строку меткой комментария «--». Весь последующий текст во время выполнения не учитывается. Вставка нескольких команд осуществляется с помощью разделителя — точки с запятой (;).
Если вставленный код SQL синтаксически верен, искаженные данные нельзя выявить программно. Поэтому необходимо проверять правильность всех вводимых пользователями данных, а также внимательно просматривать код, выполняющий созданные SQL-команды на сервере. Никогда не объединяйте введенные пользователем данные без проверки. Объединение строк является основной точкой входа для внедрения кода в сценарии.
Ниже приведены некоторые полезные рекомендации.
Ни в коем случае не следует формировать инструкции Transact-SQL непосредственно на основании данных, введенных пользователем. Используйте хранимые процедуры для проверки ввода данных пользователем.
Всегда проверяйте все данные, вводимые пользователем, выполняя проверку типа, длины, формата и диапазона данных. Применяйте функцию QUOTENAME() языка Transact-SQL для экранирования системных имен или функцию REPLACE() для экранирования любого символа в строке.
Реализуйте несколько уровней проверки в каждом уровне приложения.
Проверяйте размер и тип вводимых данных и устанавливайте соответствующие ограничения. Это поможет предотвратить преднамеренное переполнение буфера.
Проверяйте содержимое строковых переменных и принимайте только ожидаемые значения. Отклоняйте записи, содержащие двоичные данные, управляющие последовательности и символы комментариев.
При работе с XML-документами проверяйте все вводимые данные на соответствие схеме.
В многоуровневых средах все данные должны проверяться перед передачей в доверенную зону.
Не допускайте использование в полях следующих строк, из которых могут быть созданы имена файлов: AUX, CLOCK$, COM1–COM8, CON, CONFIG$, LPT1–LPT8, NUL и PRN.
Используйте объекты SqlParameter с хранимыми процедурами и командами для обеспечения контроля типов и проверки длины.
Используйте выражения Regex в клиентском коде для фильтрации недопустимых символов.
Стратегии применения динамического кода SQL
Выполнение динамически создаваемых инструкций SQL в процедурном коде нарушает цепочку владения, в результате чего SQL Server приходится проверять разрешения вызывающего объекта на объекты, доступ к которым осуществляется в динамическом коде SQL.
В SQL Server 2000 для использования динамического кода SQL необходимо предоставлять разрешения на базовые таблицы, в результате чего приложение становится уязвимым для атак путем внедрения кода SQL.
В SQL Server 2005 введены два новых метода предоставления пользователям доступа к данным с помощью хранимых процедур и определяемых пользователем функций, в которых выполняется динамический код SQL.
Использование олицетворения с помощью предложения EXECUTE AS языка Transact-SQL, как описано в разделе Настройка разрешений с олицетворением в SQL Server (ADO.NET).
Подписание хранимых процедур с применением сертификатов, как описано в разделе Подписывание хранимых процедур в SQL Server (ADO.NET).
EXECUTE AS
Предложение EXECUTE AS заменяет разрешения вызывающего объекта разрешениями пользователя, указанного в предложении EXECUTE AS. Вложенные хранимые процедуры или триггеры выполняются в контексте безопасности пользователя-посредника. Это может привести к нарушению работы приложений, которые основаны на использовании средств безопасности уровня строки или требуют аудита. Некоторые функции, возвращающие идентификатор пользователя, возвращают данные о пользователе, указанном в предложении EXECUTE AS, а не данные первоначального вызывающего объекта. Контекст выполнения переходит к вызывающему объекту только после выполнения процедуры или при выполнении инструкции REVERT.
Подписание сертификата
При выполнении хранимой процедуры, подписанной с помощью сертификата, разрешения, предоставленные пользователю сертификата, объединяются с разрешениями вызывающего объекта. Контекст выполнения остается тем же; пользователь сертификата не олицетворяет вызывающий объект. Для подписания хранимых процедур необходимо выполнить несколько действий. После каждого изменения процедуры должно быть проведено ее повторное подписание.
Доступ к объектам в нескольких базах данных
Межбазовые цепочки владения не работают при выполнении динамически создаваемых инструкций SQL. Это можно обойти в SQL Server 2005, создав хранимую процедуру для доступа к данным другой базы данных и подписав эту процедуру сертификатом, существующим в обеих базах данных. Это предоставляет пользователям доступ к используемым процедурой ресурсам базы данных без предоставления им доступа к базе данных или разрешений на нее.
Внешние ресурсы
Дополнительные сведения см. в следующих ресурсах.
Ресурс |
Описание |
---|---|
Хранимые процедуры и Внедрение кода SQL в электронной документации по SQL Server 2008. |
Разделы описывают, как создавать хранимые процедуры и как работает внедрение кода SQL. |
Хранимые процедуры и Внедрение кода SQL в электронной документации по SQL Server 2005. |
Разделы описывают, как создавать хранимые процедуры и как работает внедрение кода SQL. |
Хранимые процедуры и Использование цепочек владения в электронной документации по SQL Server 2000. |
Разделы описывают, как создавать хранимые процедуры и как использовать преимущества цепочек владения в SQL Server 2000. |
Новые виды атак по принципу отсечения SQL и их предотвращение в журнале MSDN Magazine. |
Описание того, как происходит разграничение символов и строк, внедрение кода SQL и модификация с применением атак по принципу отсечения. |
См. также
Основные понятия
Сценарии защиты приложений в SQL Server (ADO.NET)
Управление разрешениями с помощью хранимых процедур в SQL Server (ADO.NET)
Подписывание хранимых процедур в SQL Server (ADO.NET)
Настройка разрешений с олицетворением в SQL Server (ADO.NET)