Správa zabezpečení spouštěčů
platí pro:SQL Server
Azure SQL Database
azure SQL Managed Instance
Standardně se triggery DML i DDL spouští v kontextu uživatele, který trigger vyvolá. Volající aktivační události je uživatel, který spustí příkaz, který způsobí spuštění triggeru. Pokud například uživatel Mary spustí příkaz DELETE, který způsobí spuštění triggeru DML DML_trigMary, kód uvnitř DML_trigMary spustí v kontextu uživatelských oprávnění pro Mary. Toto výchozí chování můžou zneužít uživatelé, kteří chtějí zavést škodlivý kód v instanci databáze nebo serveru. Například následující trigger DDL je vytvořen uživatelem JohnDoe:
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
To znamená, že jakmile uživatel, který má oprávnění ke spuštění příkazu GRANT CONTROL SERVER
, například člen role pevného serveru sysadmin , spustí příkaz ALTER TABLE
, je uděleno oprávnění CONTROL SERVER
JohnDoe . Jinými slovy, i když JohnDoe nemůže udělit CONTROL SERVER
oprávnění sami sobě, povolili aktivační kód, který jim udělí toto oprávnění ke spuštění pod eskalovanými oprávněními. Triggery DML i DDL jsou pro tento druh bezpečnostní hrozby otevřené.
Osvědčené postupy pro aktivaci zabezpečení
Pokud chcete zabránit spuštění kódu triggeru pod eskalovanými oprávněními, můžete provést následující opatření:
Mějte na paměti triggery DML a DDL, které existují v databázi a na instanci serveru, pomocí dotazu na katalogová zobrazení sys.triggers a sys.server_triggers. Následující dotaz vrátí všechny triggery DML a DDL na úrovni databáze v aktuální databázi a všechny triggery DDL na úrovni serveru v celé instanci serveru.
SELECT type, name, parent_class_desc FROM sys.triggers UNION ALL SELECT type, name, parent_class_desc FROM sys.server_triggers;
Poznámka
Pouze sys.triggers je k dispozici pro Azure SQL Database, pokud nepoužíváte službu Azure SQL Managed Instance.
Mějte na paměti triggery DML a DDL, které existují v databázi dotazováním sys.triggers zobrazení katalogu. Následující dotaz vrátí všechny triggery DDL a DDL na úrovni databáze v aktuální databázi:
SELECT type, name, parent_class_desc FROM sys.triggers;
Pomocí ZAKÁZAT TRIGGER zakažte triggery, které můžou poškodit integritu databáze nebo serveru, pokud se triggery spouštějí pod eskalovanými oprávněními. Následující příkaz zakáže všechny triggery DDL na úrovni databáze v aktuální databázi:
DISABLE TRIGGER ALL ON DATABASE;
Tento příkaz zakáže všechny triggery DDL na úrovni serveru v instanci serveru:
DISABLE TRIGGER ALL ON ALL SERVER;
Tento příkaz zakáže všechny triggery DML v aktuální databázi:
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;
Související obsah
- CREATE TRIGGER (Transact-SQL)
- DML triggery
- DDL spouštěče
- Spouštěče přihlášení k systému