Управление безопасностью триггеровManage Trigger Security

ОБЛАСТЬ ПРИМЕНЕНИЯ: даSQL Server даБаза данных SQL Azure нетAzure Synapse Analytics (хранилище данных SQL) нетParallel Data WarehouseAPPLIES TO: yesSQL Server yesAzure SQL Database noAzure Synapse Analytics (SQL DW) noParallel Data Warehouse

Как триггеры DML, так и триггеры DDL по умолчанию выполняются в контексте того пользователя, который вызывает триггер.By default, both DML and DDL triggers execute under the context of the user that calls the trigger. Это пользователь, который выполняет инструкцию, вызывающую запуск триггера.The caller of a trigger is the user that executes the statement that causes the trigger to run. Например, если пользователь Mary выполняет инструкцию DELETE, которая запускает триггер DML DML_trigMary , то код внутри DML_trigMary выполняется в контексте прав доступа пользователя Mary.For example, if user Mary executes a DELETE statement that causes DML trigger DML_trigMary to run, the code inside DML_trigMary executes in the context of the user privileges for Mary. Этим поведением по умолчанию могут воспользоваться те пользователи, которые хотят внести небезопасный код в экземпляр базы данных или сервера.This default behavior can be exploited by users who want to introduce malicious code in the database or server instance. Например, следующий триггер DDL создан пользователем JohnDoe:For example, the following DDL trigger is created by user JohnDoe:

CREATE TRIGGER DDL_trigJohnDoe

ON DATABASE

FOR ALTER_TABLE

AS

GRANT CONTROL SERVER TO JohnDoe ;

GO

В этом триггере подразумевается, что как только пользователь с разрешением на выполнение инструкции GRANT CONTROL SERVER , например член предопределенной роли сервера sysadmin , выполнит инструкцию ALTER TABLE , пользователь JohnDoe получит права CONTROL SERVER .What this trigger means is that as soon as a user that has permission to execute a GRANT CONTROL SERVER statement, such as a member of the sysadmin fixed server role, executes an ALTER TABLE statement, JohnDoe is granted CONTROL SERVER permission. Другими словами, хотя JohnDoe не может предоставить права CONTROL SERVER самому себе, он создал код триггера, который предоставит ему разрешение работать с повышенными правами доступа.In other words, although JohnDoe cannot grant CONTROL SERVER permission to himself, he enabled the trigger code that grants him this permission to execute under escalated privileges. Эта уязвимость относится как к триггерам DML, так и к триггерам DDL.Both DML and DDL triggers are open to this kind of security threat.

Способы защиты триггеровTrigger Security Best Practices

Чтобы предотвратить выполнение кода триггера с повышенными правами доступа, примите следующие меры.You can take the following measures to prevent trigger code from executing under escalated privileges:

  • Проверьте базу данных и экземпляр сервера на наличие триггеров DDL и DDL. Для этого выполните соответствующие запросы к представлениям каталогов sys.triggers и sys.server_triggers .Be aware of the DML and DDL triggers that exist in the database and on the server instance by querying the sys.triggers and sys.server_triggers catalog views. Следующий запрос возвращает все триггеры DML и DDL уровня базы данных в текущей базе данных, а также все триггеры DDL уровня сервера на экземпляре сервера.The following query returns all DML and database-level DDL triggers in the current database, and all server-level DDL triggers on the server instance:

    SELECT type, name, parent_class_desc FROM sys.triggers  
    UNION  
    SELECT type, name, parent_class_desc FROM sys.server_triggers ;  
    

Примечание

Для Базы данных SQL Azure доступно только представление sys.triggers, если только вы не используете Управляемый экземпляр.Only sys.triggers is available for Azure SQL Database unless you are using Managed Instance.

  • Проверьте базу данных на наличие триггеров DDL и DDL. Для этого выполните соответствующие запросы к представлению каталога sys.triggers.Be aware of the DML and DDL triggers that exist in the database by querying the sys.triggers catalog view. Следующий запрос возвращает все триггеры DML и триггеры DDL уровня базы данных в текущей базе данных:The following query returns all DML and database-level DDL triggers in the current database:

    SELECT type, name, parent_class_desc FROM sys.triggers ; 
    
  • С помощью инструкции DISABLE TRIGGER запретите триггеры, которые могут нарушить целостность базы данных или сервера при выполнении с повышенными правами доступа.Use DISABLE TRIGGER to disable triggers that can harm the integrity of the database or server if the triggers execute under escalated privileges. Следующая инструкция отключает все триггеры DDL уровня базы данных в текущей базе данных:The following statement disables all database-level DDL triggers in the current database:

    DISABLE TRIGGER ALL ON DATABASE  
    

    Эта инструкция отключает все триггеры DDL уровня сервера на экземпляре сервера:This statement disables all server-level DDL triggers on the server instance:

    DISABLE TRIGGER ALL ON ALL SERVER  
    

    Эта инструкция отключает все триггеры DML в текущей базе данных:This statement disables all DML triggers in the current database:

    DECLARE @schema_name sysname, @trigger_name sysname, @object_name sysname ;  
    DECLARE @sql nvarchar(max) ;  
    DECLARE trig_cur CURSOR FORWARD_ONLY READ_ONLY FOR  
        SELECT SCHEMA_NAME(schema_id) AS schema_name,  
            name AS trigger_name,  
            OBJECT_NAME(parent_object_id) as object_name  
        FROM sys.objects WHERE type in ('TR', 'TA') ;  
    
    OPEN trig_cur ;  
    FETCH NEXT FROM trig_cur INTO @schema_name, @trigger_name, @object_name ;  
    
    WHILE @@FETCH_STATUS = 0  
    BEGIN  
        SELECT @sql = 'DISABLE TRIGGER ' + QUOTENAME(@schema_name) + '.'  
            + QUOTENAME(@trigger_name) +  
            ' ON ' + QUOTENAME(@schema_name) + '.'   
            + QUOTENAME(@object_name) + ' ; ' ;  
        EXEC (@sql) ;  
        FETCH NEXT FROM trig_cur INTO @schema_name, @trigger_name, @object_name ;  
    END  
    GO  
    
    -- Verify triggers are disabled. Should return an empty result set.  
    SELECT * FROM sys.triggers WHERE is_disabled = 0 ;  
    GO  
    
    CLOSE trig_cur ;  
    DEALLOCATE trig_cur;  
    

См. также:See Also

CREATE TRIGGER (Transact-SQL) CREATE TRIGGER (Transact-SQL)
Триггеры DML DML Triggers
Триггеры DDLDDL Triggers