Quão perigoso é conceder a permissão ALTER TABLE?

11

Imagine o seguinte cenário

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');

Em algum momento, é gravado um processo ETL que executa algumas atividades no testbanco de dados.

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*/

O etlUser não deve ter permissões para a Customertabela (e certamente não para a SensitiveDatacoluna), portanto, essas são explicitamente negadas acima.

O processo ETL trunca, dbo.StagingTableportanto, são concedidas ALTERpermissões de tabela.

Isso é sinalizado durante uma auditoria de segurança. Quão perigoso é esse cenário?

Martin Smith
fonte
Por que ações relativamente inofensivas como ALTER TABLE ADD COLUMN são tratadas da mesma forma que as outras ações (ALTER, DROP, restrições, gatilhos)?
SMCI

Respostas:

16

Muito perigoso ...

Além da permissão óbvia para alterar a estrutura em StagingTablesi, a ALTER TABLEpermissão permite que eles criem acionadores na tabela. Portanto, nesse caso, por meio do encadeamento de propriedade, eles podem ver dados confidenciais do cliente (apesar das DENYpermissões explícitas ) e realizar vandalismo nesta segunda tabela.

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
fonte
8

Além de poder adicionar gatilhos, a permissão ALTER TABLE também permite:

  1. Desativando gatilhos (evitar trilha de auditoria)
  2. Desabilitar restrições (permitindo dados incorretos)
  3. Alteração de restrições (permitindo dados incorretos)
  4. Alterando definições de coluna (alterar tipo de dados, tamanho máximo, NULLability)
  5. Adicione uma coluna computada que chama um UDF T-SQL (dificultando a obtenção de um plano paralelo, o que poderia prejudicar facilmente o desempenho)

Ele também permite a remoção de colunas, mas é provável que isso passe despercebido (pois parece que estamos procurando ações em potencial aqui mais enganosas do que maliciosas).

Felizmente, nunca é necessário conceder essa permissão a ninguém, nem é necessário envolvê-la em um procedimento armazenado que use a EXECUTE AScláusula (normalmente seguida por 'dbo'ou OWNER). A assinatura do módulo permite a fácil abstração de ações privilegiadas por trás do código assinado (procedimentos armazenados, gatilhos, UDFs escalares e TVFs com várias instruções). Eu tenho um código de exemplo mostrando como fazer isso nas seguintes respostas, aqui no DBA.SE:

A diferença entre essas duas respostas é a permissão concedida ao usuário baseado em assinatura. A permissão a ser concedida (ou a função de banco de dados a ser adicionada) depende do escopo do que é necessário. Se você precisar apenas de permissão para uma única tabela, conceda apenas ALTERa ela. Se a permissão for necessária para todas as tabelas em um esquema específico, não conceda permissão para tabelas individuais, mas conceda a permissão ao próprio esquema. E assim por diante.

A assinatura do módulo é algumas etapas extras, em comparação com a criação de um esquema especificamente para o usuário ETL ou com a EXECUTE AScláusula, mas:

  1. é realmente apenas uma cópia e colagem simples, uma vez que o código está disponível nas duas respostas acima, e
  2. é certamente a opção mais segura disponível. Ele só permite essa operação através desse trecho de código e apenas para aqueles que têm EXECUTEpermissão para esse código. Ser proprietário de um esquema permite certas permissões implícitas que são desnecessárias. E, usando EXECUTE AS 'dbo'ou EXECUTE AS OWNER(assumindo que o proprietário seja dbo) concederá permissões a todo o processo , a partir desse ponto dbo, não apenas ao procedimento / gatilho / função armazenada que você usou EXECUTE AS. A assinatura do módulo restringe as permissões apenas ao código que você assinou, e não a qualquer código chamado pelo código assinado.
Solomon Rutzky
fonte
2
Em alguns sistemas (pelo menos em algumas versões do MySQL), existe uma maneira realmente desagradável de obliterar efetivamente uma coluna VARCHAR sem que ela seja notada instantaneamente por programas errados: reduza o tamanho para 0. Isso o limpará e descartará silenciosamente qualquer coisa escrita para -lo ...
rackandboneman
2

Uma prática melhor seria criar um esquema de temporariedade, de propriedade do usuário ETL. Em seguida, o processo ETL pode truncar tabelas, desabilitar restrições, executar alternância de partições etc. no esquema de preparação. O usuário ETL precisaria apenas de permissão limitada nos outros esquemas.

Você também pode usar uma função de banco de dados em vez de um único usuário.

Obviamente, você também pode permitir que seu usuário limitado execute truncamentos de tabela com um procedimento armazenado de propriedade do dbo, como este:

create procedure truncate_t 
with execute as owner
as
begin
  truncate table t;
end
David Browne - Microsoft
fonte