Aracılığıyla paylaş


Tetikleyici güvenliğini yönetme

Şunlar için geçerlidir:SQL ServerAzure SQL VeritabanıAzure SQL Yönetilen Örneği

Varsayılan olarak, hem DML hem de DDL tetikleyicileri tetikleyiciyi çağıran kullanıcının bağlamı altında yürütülür. Tetikleyicinin çağıranı, tetikleyicinin çalışmasını başlatan ifadeyi yürüten kullanıcıdır. Örneğin, Kullanıcı Mary DML tetikleyicisi DML_trigMary çalışmasına neden olan bir DELETE deyimi yürütürse, DML_trigMary içindeki kod Maryiçin kullanıcı ayrıcalıkları bağlamında yürütülür. Bu varsayılan davranış, veritabanında veya sunucu örneğinde kötü amaçlı kod eklemek isteyen kullanıcılar tarafından kötüye kullanılabilir. Örneğin, kullanıcı JohnDoetarafından aşağıdaki DDL tetikleyicisi oluşturulur:

CREATE TRIGGER DDL_trigJohnDoe
ON DATABASE
FOR ALTER_TABLE
AS
SET NOCOUNT ON;

BEGIN TRY
  EXEC(N'
    USE [master];
    GRANT CONTROL SERVER TO [JohnDoe];
');
END TRY
BEGIN CATCH
  DECLARE @DoNothing INT;
END CATCH;
GO

Bu tetikleyicinin anlamı, sysadmin sabit sunucu rolünün bir üyesi gibi, GRANT CONTROL SERVER deyimini yürütme iznine sahip olan bir kullanıcı ALTER TABLE deyimini yürüttüğünde, JohnDoe'ye CONTROL SERVER izni verilmesidir. Başka bir deyişle, JohnDoe kendilerine CONTROL SERVER izin veremese de, onlara yükseltilmiş ayrıcalıklar altında yürütme izni veren tetikleyici kodunu etkinleştirdiler. Hem DML hem de DDL tetikleyicileri bu tür bir güvenlik tehdidine açıktır.

En iyi güvenlik uygulamalarını tetikleme

Tetikleyici kodunun yükseltilmiş ayrıcalıklar altında yürütülmesini önlemek için aşağıdaki ölçüleri alabilirsiniz:

  • sys.triggers ve sys.server_triggers katalog görünümlerini sorgulayarak veritabanında ve sunucu örneğinde var olan DML ve DDL tetikleyicilerine dikkat edin. Aşağıdaki sorgu geçerli veritabanındaki tüm DML ve veritabanı düzeyinde DDL tetikleyicilerini ve sunucu örneğindeki tüm sunucu düzeyinde DDL tetikleyicilerini döndürür:

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

    Not

    Azure SQL Yönetilen Örneği kullanmıyorsanız Azure SQL Veritabanı için yalnızca sys.triggers kullanılabilir.

  • sys.triggers katalog görünümünü sorgulayarak veritabanında var olan DML ve DDL tetikleyicilerine dikkat edin. Aşağıdaki sorgu geçerli veritabanındaki tüm DML ve veritabanı düzeyinde DDL tetikleyicilerini döndürür:

    SELECT type, name, parent_class_desc FROM sys.triggers;
    
  • Tetikleyiciler yükseltilmiş ayrıcalıklar altında yürütülürse veritabanı veya sunucunun bütünlüğüne zarar veren tetikleyicileri devre dışı bırakmak için DISABLE TRIGGER kullanın. Aşağıdaki deyim geçerli veritabanındaki tüm veritabanı düzeyinde DDL tetikleyicilerini devre dışı bırakır:

    DISABLE TRIGGER ALL ON DATABASE;
    

    Bu deyim, sunucu örneğindeki tüm sunucu düzeyinde DDL tetikleyicilerini devre dışı bırakır:

    DISABLE TRIGGER ALL ON ALL SERVER;
    

    Bu deyim geçerli veritabanındaki tüm DML tetikleyicilerini devre dışı bırakır:

    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 = N'DISABLE TRIGGER ' + QUOTENAME(@schema_name) + N'.'
            + QUOTENAME(@trigger_name)
            + N' ON ' + QUOTENAME(@schema_name) + N'.'
            + QUOTENAME(@object_name) + N'; ';
        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;