Imaginez le scénario suivant
CREATE DATABASE test
GO
USE test;
CREATE TABLE dbo.Customer
(
CustomerId INT,
Email VARCHAR(100),
SensitiveData VARCHAR(20)
);
INSERT INTO dbo.Customer
VALUES (1,'[email protected]','12346789');
À un moment donné, un processus ETL est écrit qui effectue certaines activités dans la base de données test
.
CREATE USER etlUser WITHOUT LOGIN; /*For demo purposes*/
CREATE TABLE dbo.StagingTable
(
StagingTableId INT,
SomeData VARCHAR(100),
)
GRANT UPDATE,INSERT,DELETE,SELECT,ALTER ON dbo.StagingTable TO etlUser;
DENY SELECT ON dbo.Customer TO etlUser;
DENY SELECT ON dbo.Customer (SensitiveData) TO etlUser; /*For good measure*/
L'utilisateur etlUser ne doit pas avoir d'autorisations sur la table Customer
(et certainement pas sur la colonne SensitiveData
), donc celles-ci sont explicitement refusées ci-dessus.
Le processus ETL tronque dbo.StagingTable
donc est donné ALTER
les autorisations de table sur cela.
Ceci est signalé lors d'un audit de sécurité. À quel point ce scénario est-il dangereux?
Assez dangereux ...
En plus de l'autorisation évidente de modifier la structure de StagingTable
lui-même, le ALTER TABLE
l'autorisation leur permet de créer des déclencheurs sur la table. Dans ce cas, grâce au chaînage de propriété, ils peuvent à la fois voir les données sensibles des clients (malgré les autorisations explicites DENY
) et effectuer du vandalisme sur cette deuxième table.
EXECUTE AS user='etlUser'
GO
CREATE OR ALTER TRIGGER TR ON dbo.StagingTable AFTER UPDATE AS
/*Exposure of sensitive data*/
SELECT * FROM dbo.Customer;
/*Vandalism*/
DELETE FROM dbo.Customer;
go
--Fire the trigger
UPDATE dbo.StagingTable SET SomeData = SomeData WHERE 1=0;
REVERT
En plus de pouvoir ajouter des déclencheurs, l'autorisation ALTER TABLE permet également:
Il permet également de supprimer des colonnes, mais cela ne passera probablement pas inaperçu (car il semble que nous recherchons ici des actions potentielles plus trompeuses que malveillantes).
Heureusement, il n'est jamais nécessaire d'accorder cette autorisation à qui que ce soit, ni de l'envelopper dans une procédure stockée qui utilise le EXECUTE AS
clause (généralement suivie de 'dbo'
ou OWNER
). Signature du module permet une abstraction facile des actions privilégiées derrière le code signé (procédures stockées, déclencheurs, UDF scalaires et TVF multi-instructions). J'ai un exemple de code montrant comment accomplir cela dans les réponses suivantes, ici sur DBA.SE:
La différence entre ces deux réponses est l'autorisation accordée à l'utilisateur basé sur la signature. L'autorisation à accorder (ou le rôle de base de données à ajouter) dépend de l'étendue de ce qui est nécessaire. Si vous n'avez besoin que d'une autorisation pour une seule table, accordez uniquement ALTER
sur cette table. Si une autorisation est nécessaire pour toutes les tables d'un schéma spécifique, n'accordez pas d'autorisation à des tables individuelles, mais accordez plutôt l'autorisation au schéma lui-même. Etc.
La signature de module représente quelques étapes supplémentaires par rapport à la création d'un schéma spécifiquement pour l'utilisateur ETL ou à l'aide de EXECUTE AS
clause, mais:
EXECUTE
pour ce code. Être propriétaire d'un schéma autorise certaines autorisations implicites inutiles. Et, en utilisant EXECUTE AS 'dbo'
ou EXECUTE AS OWNER
(en supposant que le propriétaire est dbo
) donnera au processus entier , à partir de ce moment, dbo
autorisations , pas seulement la procédure/déclencheur/fonction stockée que vous avez utilisée EXECUTE AS
avec. La signature du module limite les autorisations uniquement au code que vous avez signé, et non à tout code appelé par le code signé.Une meilleure pratique serait de créer un schéma de transfert, détenu par l'utilisateur ETL. Ensuite, le processus ETL peut tronquer les tables, désactiver les contraintes, effectuer une commutation de partition, etc. dans le schéma de transfert. L'utilisateur ETL n'aurait besoin que d'une autorisation limitée sur les autres schémas.
Vous pouvez également utiliser un rôle de base de données au lieu d'un seul utilisateur.
Bien sûr, vous pouvez également permettre à votre utilisateur limité d'effectuer des troncatures de table avec une procédure stockée appartenant à dbo, comme ceci:
create procedure truncate_t
with execute as owner
as
begin
truncate table t;
end