¿Qué tan peligroso es otorgar el permiso ALTER TABLE?

11

Imagine el siguiente escenario

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

En algún momento se escribe un proceso ETL que realiza algunas actividades en la testbase de datos.

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

El etlUser no debe tener permisos para la Customertabla (y ciertamente no para la SensitiveDatacolumna), por lo que estos se niegan explícitamente anteriormente.

El proceso ETL se trunca, dbo.StagingTablepor lo que se le otorgan ALTERpermisos de tabla.

Esto se marca durante una auditoría de seguridad. ¿Qué tan peligroso es este escenario?

Martin Smith
fuente
¿Por qué las acciones relativamente inofensivas como ALTER TABLE ADD COLUMN se tratan igual que las otras acciones (ALTER, DROP, restricciones, desencadenantes)?
smci

Respuestas:

16

Bastante peligroso ...

Además del permiso obvio para cambiar la estructura de StagingTablesí mismo, el ALTER TABLEpermiso les permite crear desencadenantes en la tabla. Entonces, en este caso, a través del encadenamiento de propiedad, pueden ver datos confidenciales del cliente (a pesar de los DENYpermisos explícitos ) y realizar actos de vandalismo en esta segunda tabla.

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

Además de poder agregar desencadenantes, el permiso ALTER TABLE también permite:

  1. Deshabilitar los desencadenantes (evitar el seguimiento de auditoría)
  2. Deshabilitar restricciones (permitiendo datos incorrectos)
  3. Alteración de las improntas (permitiendo datos incorrectos)
  4. Alterar definiciones de columna (cambiar tipo de datos, tamaño máximo, NULLability)
  5. Agregue una columna calculada que llame a un UDF T-SQL (lo que hace que sea muy difícil obtener un plan paralelo, lo que podría dañar fácilmente el rendimiento)

También permite eliminar columnas, pero es probable que no pase desapercibido (ya que parece que estamos buscando acciones potenciales aquí que sean más engañosas que maliciosas).

Afortunadamente, nunca es necesario otorgar este permiso a nadie, ni es necesario envolverlo en un procedimiento almacenado que use la EXECUTE AScláusula (generalmente seguido de 'dbo'o OWNER). La firma de módulos permite una fácil abstracción de acciones privilegiadas detrás del código firmado (procedimientos almacenados, disparadores, UDF escalares y TVF de múltiples declaraciones). Tengo un código de ejemplo que muestra cómo lograr esto en las siguientes respuestas, aquí en DBA.SE:

La diferencia entre esas dos respuestas es el permiso otorgado al Usuario basado en firma. El permiso que se debe otorgar (o el rol de DB para agregar) depende del alcance de lo que se necesita. Si solo necesita permiso para una sola tabla, solo otorgue ALTERen esa tabla. Si se necesita permiso para todas las tablas en un Esquema específico, no otorgue permiso a tablas individuales, sino que otorgue el permiso al Esquema mismo. Y así.

La firma del módulo son algunos pasos adicionales en comparación con la creación de un esquema específicamente para el usuario de ETL o el uso de la EXECUTE AScláusula, pero:

  1. en realidad es solo una simple copia y pega dado que el código está disponible en ambas respuestas vinculadas anteriormente, y
  2. Sin duda, es la opción más segura disponible. Solo permite esa operación a través de ese fragmento de código, y solo a aquellos que tienen EXECUTEpermiso para ese código. Ser propietario de un esquema permite ciertos permisos implícitos que son innecesarios. Y, usar EXECUTE AS 'dbo'o EXECUTE AS OWNER(suponiendo que el propietario lo es dbo) le dará a todo el proceso , desde ese momento en adelante, dbopermisos, no solo el procedimiento almacenado / disparador / función con la que usó EXECUTE AS. La firma del módulo limita los permisos solo al código que firmó, y no a ningún código invocado por el código firmado.
Solomon Rutzky
fuente
2
Con algunos sistemas (al menos algunas versiones de MySQL), hay una manera realmente cobarde de eliminar de manera efectiva una columna VARCHAR sin que se noten instantáneamente por errores de los programas: reduzca su tamaño a 0. Esto lo borrará y descartará silenciosamente cualquier cosa escrita en it ...
rackandboneman
2

Una mejor práctica sería crear un esquema de etapas, propiedad del usuario ETL. Luego, el proceso ETL puede truncar tablas, deshabilitar restricciones, realizar el cambio de partición, etc. dentro del esquema de preparación. El usuario ETL solo necesitaría un permiso limitado en los otros esquemas.

También puede usar una función de base de datos en lugar de un solo usuario.

Por supuesto, también puede permitir que su usuario limitado realice truncamientos de tabla con un procedimiento almacenado propiedad de dbo, como este:

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