Freigeben über


Verwalten der Triggersicherheit

Gilt für: SQL Server Azure SQL-Datenbank Azure SQL Managed Instance

Standardmäßig werden sowohl DML- als auch DDL-Trigger im Kontext des Benutzers ausgeführt, der den Trigger aufruft. Genauer ist der Benutzer, der den Trigger aufruft, derjenige Benutzer, der die Anweisung ausführt, die zum Ausführen des Triggers führt. Wenn die Benutzerin Mary beispielsweise eine DELETE-Anweisung ausführt, die dazu führt, dass der DML-Trigger DML_trigMary ausgeführt wird, wird der Code in DML_trigMary im Kontext der Privilegien für Maryausgeführt. Dieses Standardverhalten kann von Benutzern ausgenutzt werden, die bösartigen Code in die Datenbank oder Serverinstanz einschleusen möchten. Beispielsweise wird der folgende DDL-Trigger vom Benutzer JohnDoe erstellt:

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

Dieser Trigger bewirkt Folgendes: Sobald ein Benutzer mit der Berechtigung, GRANT CONTROL SERVER-Anweisungen auszuführen, wie z. B. ein Mitglied der festen Serverrolle sysadmin, eine ALTER TABLE-Anweisung ausführt, wird JohnDoe die CONTROL SERVER-Berechtigung erteilt. Mit anderen Worten heißt dies, dass JohnDoe zwar die CONTROL SERVER-Berechtigung nicht sich selbst erteilen darf, jedoch den Triggercode aktivieren kann, der ihm diese Berechtigung verschafft. Sowohl DML- als auch DDL-Trigger sind diesen Sicherheitsrisiken ausgesetzt.

Bewährte Methoden für die Triggersicherheit

Sie können folgende Maßnahmen ergreifen, um zu vermeiden, dass Triggercode mit ausgeweiteten Privilegien ausgeführt wird:

  • Eruieren Sie die in der Datenbank und der Serverinstanz vorhandenen DML- und DDL-Trigger, indem Sie die Katalogsichten sys.triggers und sys.server_triggers abfragen. Die folgende Abfrage gibt alle DML-Trigger und DDL-Trigger auf Datenbankebene der aktuellen Datenbank zurück, sowie alle DDL-Trigger auf Serverebene der Serverinstanz:

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

    Hinweis

    Nur sys.triggers ist für Azure SQL-Datenbank verfügbar, wenn Sie nicht Azure SQL Managed Instance verwenden.

  • Beachten Sie die in der Datenbank vorhandenen DML- und DDL-Trigger, indem Sie die Katalogsicht sys.triggers abfragen. Die folgende Abfrage gibt alle DML-Trigger und DDL-Trigger auf Datenbankebene in der aktuellen Datenbank zurück:

    SELECT type, name, parent_class_desc FROM sys.triggers;
    
  • Verwenden Sie DISABLE TRIGGER , um die Trigger zu deaktivieren, die die Integrität der Datenbank oder des Servers beeinträchtigen können, falls sie mit ausgeweiteten Privilegien ausgeführt werden. Die folgende Anweisung deaktiviert alle DDL-Trigger auf Datenbankebene in der aktuellen Datenbank:

    DISABLE TRIGGER ALL ON DATABASE;
    

    Die folgende Anweisung deaktiviert alle DDL-Trigger auf Serverebene in der Serverinstanz:

    DISABLE TRIGGER ALL ON ALL SERVER;
    

    Die folgende Anweisung deaktiviert alle DML-Trigger in der aktuellen Datenbank:

    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;