トリガーのセキュリティの管理Manage Trigger Security

適用対象: ○SQL Server ○Azure SQL Database XAzure SQL Data Warehouse XParallel Data WarehouseAPPLIES TO: yesSQL Server yesAzure SQL Database noAzure SQL Data Warehouse 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 ステートメントを実行した直後に、 JohnDoeCONTROL 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:

  • sys.triggers カタログ ビューと sys.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 ;  
    

注意

Managed Instance を使用している場合を除き、Azure SQL Database で使用できるのは sys.triggers のみです。Only sys.triggers is available for Azure SQL Database unless you are using Managed Instance.

  • sys.triggers カタログ ビューに対してクエリを実行して、データベースに存在する DML および DDL トリガーを認識します。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
DDL トリガーDDL Triggers