트리거 보안 관리Manage Trigger Security

기본적으로 두 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 라는 사용자가 DML 트리거 DML_trigMary 를 실행시키는 DELETE 문을 실행하면 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. 즉, JohnDoeCONTROL 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:

  • sys.triggerssys.server_triggers 카탈로그 뷰를 쿼리하여 데이터베이스 및 서버 인스턴스에 있는 DML 및 DDL 트리거를 확인합니다.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 ;  
    
  • 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
DDL 트리거DDL Triggers