Dans quelle mesure l'octroi de l'autorisation ALTER TABLE est-il dangereux?

11

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 testbase de données.

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'etlUser ne devrait pas avoir d'autorisations sur la Customertable (et certainement pas sur la SensitiveDatacolonne) donc celles-ci sont explicitement refusées ci-dessus.

Le processus ETL tronque dbo.StagingTabledonc est donné ALTERdes autorisations de table à ce sujet.

Ceci est signalé lors d'un audit de sécurité. Dans quelle mesure ce scénario est-il dangereux?

Martin Smith
la source
Pourquoi les actions relativement inoffensives comme ALTER TABLE ADD COLUMN sont-elles traitées de la même manière que les autres actions (ALTER, DROP, contraintes, triggers)?
smci

Réponses:

16

Assez dangereux ...

En plus de l'autorisation évidente de modifier la structure de StagingTablelui-même, l' ALTER TABLEautorisation leur permet de créer des déclencheurs sur la table. Ainsi, dans ce cas, grâce au chaînage de propriété, ils peuvent à la fois voir les données sensibles des clients (malgré les DENYautorisations explicites ) 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
Martin Smith
la source
8

En plus de pouvoir ajouter des déclencheurs, l' autorisation ALTER TABLE permet également:

  1. Désactiver les déclencheurs (éviter la piste d'audit)
  2. Désactiver les contraintes (autoriser les mauvaises données)
  3. Modifier les contraintes (autoriser les mauvaises données)
  4. Modification des définitions de colonne (modification du type de données, taille maximale, NULLability)
  5. Ajouter une colonne calculée qui appelle un UDF T-SQL (ce qui rend très difficile l'obtention d'un plan parallèle, ce qui pourrait facilement nuire aux performances)

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 la EXECUTE ASclause (généralement suivie de 'dbo'ou OWNER). La signature de 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-la uniquement ALTERsur 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'utilisation de la EXECUTE ASclause, mais:

  1. c'est vraiment juste un simple copier-coller étant donné que le code est disponible dans les deux réponses liées ci-dessus, et
  2. c'est certainement l'option la plus sûre disponible. Il permet uniquement cette opération via ce morceau de code, et uniquement à ceux EXECUTEautorisés à utiliser 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 à l' ensemble du processus , à partir de ce moment, des dboautorisations, pas seulement la procédure / déclencheur / fonction stockée EXECUTE ASavec laquelle vous avez utilisé . La signature du module limite les autorisations uniquement au code que vous avez signé, et non à tout code appelé par le code signé.
Solomon Rutzky
la source
2
Avec certains systèmes (au moins certaines versions de MySQL), il existe un moyen vraiment ignoble d'effacer efficacement une colonne VARCHAR sans qu'elle ne soit instantanément remarquée par les programmes qui se trompent: réduisez sa taille à 0. Cela l'effacera et supprimera silencieusement tout ce qui est écrit dans il ...
rackandboneman
2

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
David Browne - Microsoft
la source