다음을 통해 공유


트리거 보안 관리

기본적으로 두 DML 및 DDL 트리거는 트리거를 호출하는 사용자의 컨텍스트에서 모두 실행됩니다. 트리거 호출자는 트리거를 실행시키는 문을 실행하는 사용자입니다. 예를 들어 Mary 라는 사용자가 DML 트리거 DML_trigMary 를 실행시키는 DELETE 문을 실행하면 DML_trigMary 내에 있는 코드는 Mary에 대한 사용자 권한 컨텍스트에서 실행됩니다. 이 기본 동작은 데이터베이스 또는 서버 인스턴스에 악성 코드를 도입하려는 사용자가 악용할 수 있습니다. 예를 들어 다음 DDL 트리거는 사용자가 JohnDoe만듭니다.

CREATE TRIGGER DDL_trigJohnDoe

ON DATABASE

FOR ALTER_TABLE

AS

GRANT CONTROL SERVER TO JohnDoe ;

GO

이 트리거의 의미는 sysadmin 고정 서버 역할의 멤버와 같이 GRANT CONTROL SERVER 문을 실행할 수 있는 권한이 있는 사용자가 ALTER TABLE 문을 실행하면 JohnDoeCONTROL SERVER 사용 권한이 즉시 부여된다는 것입니다. 즉, JohnDoe은 자신에게 CONTROL SERVER 권한을 직접 부여할 수 없지만, 에스컬레이션된 권한으로 실행할 수 있도록 이 권한을 승인하는 트리거 코드를 활성화했습니다. DML 및 DDL 트리거는 모두 이러한 종류의 보안 위협에 열려 있습니다.

트리거 보안 모범 사례

트리거 코드가 에스컬레이션된 권한으로 실행되지 않도록 하기 위해 다음 조치를 취할 수 있습니다.

  • sys.triggerssys.server_triggers 카탈로그 뷰를 쿼리하여 데이터베이스와 서버 인스턴스에 있는 DML 및 DDL 트리거를 확인합니다. 다음 쿼리는 현재 데이터베이스의 모든 DML 및 데이터베이스 수준 DDL 트리거와 서버 인스턴스의 모든 서버 수준 DDL 트리거를 반환합니다.

    SELECT type, name, parent_class_desc FROM sys.triggers  
    UNION  
    SELECT type, name, parent_class_desc FROM sys.server_triggers ;  
    
  • DISABLE TRIGGER를 사용하여 트리거가 에스컬레이션된 권한으로 실행되는 경우 데이터베이스 또는 서버의 무결성을 손상시킬 수 있는 트리거를 사용하지 않도록 설정합니다. 다음 문은 현재 데이터베이스의 모든 데이터베이스 수준 DDL 트리거를 사용하지 않도록 설정합니다.

    DISABLE TRIGGER ALL ON DATABASE  
    

    이 문은 서버 인스턴스에서 모든 서버 수준 DDL 트리거를 비활성화합니다.

    DISABLE TRIGGER ALL ON ALL SERVER  
    

    이 문은 현재 데이터베이스의 모든 DML 트리거를 사용하지 않도록 설정합니다.

    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;  
    

또한 참조하십시오

CREATE TRIGGER(Transact-SQL)
DML 트리거
DDL 트리거