Eseményindító biztonságának kezelése

A következőkre vonatkozik:SQL ServerAzure SQL DatabaseFelügyelt Azure SQL-példánySQL-adatbázis a Microsoft Fabricben

Alapértelmezés szerint a DML és a DDL-eseményindítók is az eseményindítót hívó felhasználó környezetében futnak. Az eseményindító hívója az a felhasználó, aki végrehajtja az eseményindító futtatását okozó utasítást. Ha például Mary felhasználó egy DELETE utasítást hajt végre, amely miatt a DML-eseményindító DML_trigMary fut, a DML_trigMary belül lévő kód a Mary felhasználói jogosultságainak kontextusában fut. Ezt az alapértelmezett viselkedést kihasználhatják azok a felhasználók, akik rosszindulatú kódot szeretnének bevezetni az adatbázisban vagy a kiszolgálópéldányban. A következő DDL-eseményindítót például JohnDoe felhasználó hozza létre:

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

Ez az eseményindító azt jelenti, hogy amint egy olyan felhasználó, aki engedéllyel rendelkezik egy GRANT CONTROL SERVER utasítás végrehajtására, például a sysadmin rögzített kiszolgálói szerepkör tagja, végrehajt egy utasítást ALTER TABLE , JohnDoe engedélyt kap CONTROL SERVER . Más szóval, bár a JohnDoe nem tud engedélyt adni CONTROL SERVER maguknak, engedélyezte az eseményindító kódot, amely engedélyezi nekik ezt az engedélyt az eszkalált jogosultságok alatt való végrehajtásra. A DML és a DDL-eseményindítók is nyitottak az ilyen típusú biztonsági fenyegetésekre.

Ajánlott biztonsági eljárások aktiválása

Az alábbi intézkedésekkel megakadályozhatja, hogy az eseményindító kód eszkalált jogosultságok alatt futjon:

  • A sys.triggersés sys.server_triggers katalógusnézetek lekérdezésével vegye figyelembe az adatbázisban és a kiszolgálópéldányban található DML- és DDL-eseményindítókat. A következő lekérdezés az aktuális adatbázisban lévő összes DML- és adatbázisszintű DDL-eseményindítót, valamint a kiszolgálópéldány összes kiszolgálószintű DDL-eseményindítóit adja vissza:

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

    Megjegyzés:

    Csak sys.triggerek érhetők el az Azure SQL Database-hez, kivéve, ha felügyelt Azure SQL-példányt használ.

  • A sys.triggers katalógusnézet lekérdezésével vegye figyelembe az adatbázisban található DML- és DDL-eseményindítókat. Az alábbi lekérdezés az aktuális adatbázisban lévő összes DML- és adatbázisszintű DDL-eseményindítót adja vissza:

    SELECT type, name, parent_class_desc FROM sys.triggers;
    
  • A DISABLE TRIGGER használatával tiltsa le azokat az eseményindítókat, amelyek károsíthatják az adatbázis vagy a kiszolgáló integritását, ha az eseményindítók eszkalált jogosultságok mellett futnak. Az alábbi utasítás letiltja az adatbázisszintű DDL-eseményindítókat az aktuális adatbázisban:

    DISABLE TRIGGER ALL ON DATABASE;
    

    Ez az utasítás letiltja a kiszolgálópéldány összes kiszolgálószintű DDL-eseményindítót:

    DISABLE TRIGGER ALL ON ALL SERVER;
    

    Ez az utasítás letiltja az összes DML-eseményindítót az aktuális adatbázisban:

    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;