Написание безопасного динамического кода SQL в SQL ServerWriting Secure Dynamic SQL in SQL Server

Внедрение кода SQL - это процесс, посредством которого пользователь-злоумышленник вводит инструкции языка Transact-SQL вместо допустимых входных данных.SQL Injection is the process by which a malicious user enters Transact-SQL statements instead of valid input. Если входные данные передаются непосредственно на сервер без проверки, и если в приложении не приняты меры против выполнения внедренного кода, то появляется возможность осуществлять злонамеренные действия для повреждения или уничтожения данных.If the input is passed directly to the server without being validated and if the application inadvertently executes the injected code, the attack has the potential to damage or destroy data.

Любая процедура, создающая инструкции SQL, должна рассматриваться на предмет уязвимости к внедрению небезопасного кода, поскольку SQL Server выполняет все получаемые синтаксически правильные запросы.Any procedure that constructs SQL statements should be reviewed for injection vulnerabilities because SQL Server will execute all syntactically valid queries that it receives. Даже параметризованные данные могут стать предметом манипуляций опытного и решительного злоумышленника.Even parameterized data can be manipulated by a skilled and determined attacker. В случае применения динамического кода SQL следует обязательно параметризовать применяемые команды и никогда не включать значения параметров непосредственно в строку запроса.If you use dynamic SQL, be sure to parameterize your commands, and never include parameter values directly into the query string.

Принцип осуществления атаки путем внедрения кода SQLAnatomy of a SQL Injection Attack

Атака осуществляется посредством преждевременного завершения текстовой строки и присоединения к ней новой команды.The injection process works by prematurely terminating a text string and appending a new command. Поскольку к вставленной команде перед выполнением могут быть добавлены дополнительные строки, злоумышленник заканчивает внедряемую строку меткой комментария «--».Because the inserted command may have additional strings appended to it before it is executed, the malefactor terminates the injected string with a comment mark "--". Весь последующий текст во время выполнения не учитывается.Subsequent text is ignored at execution time. Вставка нескольких команд осуществляется с помощью разделителя - точки с запятой (;).Multiple commands can be inserted using a semicolon (;) delimiter.

Если вставленный код SQL синтаксически верен, искаженные данные нельзя выявить программно.As long as injected SQL code is syntactically correct, tampering cannot be detected programmatically. Поэтому необходимо проверять правильность всех вводимых пользователями данных, а также внимательно просматривать код, выполняющий созданные SQL-команды на сервере.Therefore, you must validate all user input and carefully review code that executes constructed SQL commands in the server that you are using. Никогда не объединяйте введенные пользователем данные без проверки.Never concatenate user input that is not validated. Объединение строк является основной точкой входа для внедрения кода в скрипте.String concatenation is the primary point of entry for script injection.

Ниже приведены некоторые полезные рекомендации.Here are some helpful guidelines:

  • Ни в коем случае не следует формировать инструкции Transact-SQL непосредственно на основании данных, введенных пользователем. Используйте хранимые процедуры для проверки ввода данных пользователем.Never build Transact-SQL statements directly from user input; use stored procedures to validate user input.

  • Всегда проверяйте все данные, вводимые пользователем, выполняя проверку типа, длины, формата и диапазона данных.Validate user input by testing type, length, format, and range. Применяйте функцию QUOTENAME() языка Transact-SQL для экранирования системных имен или функцию REPLACE() для экранирования любого символа в строке.Use the Transact-SQL QUOTENAME() function to escape system names or the REPLACE() function to escape any character in a string.

  • Реализуйте несколько уровней проверки в каждом уровне приложения.Implement multiple layers of validation in each tier of your application.

  • Проверяйте размер и тип вводимых данных и устанавливайте соответствующие ограничения.Test the size and data type of input and enforce appropriate limits. Это поможет предотвратить преднамеренное переполнение буфера.This can help prevent deliberate buffer overruns.

  • Проверяйте содержимое строковых переменных и принимайте только ожидаемые значения.Test the content of string variables and accept only expected values. Отклоняйте записи, содержащие двоичные данные, управляющие последовательности и символы комментариев.Reject entries that contain binary data, escape sequences, and comment characters.

  • При работе с XML-документами проверяйте все вводимые данные на соответствие схеме.When you are working with XML documents, validate all data against its schema as it is entered.

  • В многоуровневых средах все данные должны проверяться перед передачей в доверенную зону.In multi-tiered environments, all data should be validated before admission to the trusted zone.

  • Не допускайте использование в полях следующих строк, из которых могут быть созданы имена файлов: AUX, CLOCK$, COM1–COM8, CON, CONFIG$, LPT1–LPT8, NUL и PRN.Do not accept the following strings in fields from which file names can be constructed: AUX, CLOCK$, COM1 through COM8, CON, CONFIG$, LPT1 through LPT8, NUL, and PRN.

  • Используйте объекты SqlParameter с хранимыми процедурами и командами для обеспечения контроля типов и проверки длины.Use SqlParameter objects with stored procedures and commands to provide type checking and length validation.

  • Используйте выражения Regex в клиентском коде для фильтрации недопустимых символов.Use Regex expressions in client code to filter invalid characters.

Стратегии применения динамического кода SQLDynamic SQL Strategies

Выполнение динамически создаваемых инструкций SQL в процедурном коде нарушает цепочку владения, в результате чего SQL Server приходится проверять разрешения вызывающего объекта на объекты, доступ к которым осуществляется в динамическом коде SQL.Executing dynamically created SQL statements in your procedural code breaks the ownership chain, causing SQL Server to check the permissions of the caller against the objects being accessed by the dynamic SQL.

В SQL Server имеются методы предоставления пользователям доступа к данным с помощью хранимых процедур и определяемых пользователем функций, в которых выполняется динамический код SQL.SQL Server has methods for granting users access to data using stored procedures and user-defined functions that execute dynamic SQL.

EXECUTE ASEXECUTE AS

Предложение EXECUTE AS заменяет разрешения вызывающего объекта разрешениями пользователя, указанного в предложении EXECUTE AS.The EXECUTE AS clause replaces the permissions of the caller with that of the user specified in the EXECUTE AS clause. Вложенные хранимые процедуры или триггеры выполняются в контексте безопасности пользователя-посредника.Nested stored procedures or triggers execute under the security context of the proxy user. Это может привести к нарушению работы приложений, которые основаны на использовании средств безопасности уровня строки или требуют аудита.This can break applications that rely on row-level security or require auditing. Некоторые функции, возвращающие идентификатор пользователя, возвращают данные о пользователе, указанном в предложении EXECUTE AS, а не данные первоначального вызывающего объекта.Some functions that return the identity of the user return the user specified in the EXECUTE AS clause, not the original caller. Контекст выполнения переходит к вызывающему объекту только после выполнения процедуры или при выполнении инструкции REVERT.Execution context is reverted to the original caller only after execution of the procedure or when a REVERT statement is issued.

Подпись сертификатаCertificate Signing

При выполнении хранимой процедуры, подписанной с помощью сертификата, разрешения, предоставленные пользователю сертификата, объединяются с разрешениями вызывающего объекта.When a stored procedure that has been signed with a certificate executes, the permissions granted to the certificate user are merged with those of the caller. Контекст выполнения остается тем же; пользователь сертификата не олицетворяет вызывающий объект.The execution context remains the same; the certificate user does not impersonate the caller. Для подписания хранимых процедур необходимо выполнить несколько действий.Signing stored procedures requires several steps to implement. После каждого изменения процедуры должно быть проведено ее повторное подписание.Each time the procedure is modified, it must be re-signed.

Доступ к объектам в нескольких базах данныхCross Database Access

Межбазовые цепочки владения не работают при выполнении динамически создаваемых инструкций SQL.Cross-database ownership chaining does not work in cases where dynamically created SQL statements are executed. Это можно обойти в SQL Server, создав хранимую процедуру для доступа к данным другой базы данных и подписав эту процедуру сертификатом, существующим в обеих базах данных.You can work around this in SQL Server by creating a stored procedure that accesses data in another database and signing the procedure with a certificate that exists in both databases. Это предоставляет пользователям доступ к используемым процедурой ресурсам базы данных без предоставления им доступа к базе данных или разрешений на нее.This gives users access to the database resources used by the procedure without granting them database access or permissions.

Внешние ресурсыExternal Resources

Дополнительные сведения см. в следующих ресурсах.For more information, see the following resources.

ResourceResource ОписаниеDescription
Хранимые процедуры и Внедрение кода SQL в электронной документации на SQL ServerStored Procedures and SQL Injection in SQL Server Books Online Разделы описывают, как создавать хранимые процедуры и как работает внедрение кода SQL.Topics describe how to create stored procedures and how SQL Injection works.

См. такжеSee also