SQL Server en la práctica

Acceso a procedimientos SQL Server con privilegios mínimos

Concede operaciones mediante roles, entiende las cadenas de propiedad y prueba los permisos efectivos con una identidad de aplicación limitada.

Una aplicación que solo necesita un resumen de facturas no requiere editar todas las tablas ni cambiar el esquema. Conceder db_owner puede hacer desaparecer errores de despliegue mientras oculta las dependencias reales. Una superficie pequeña de permisos se revisa mejor y resulta más estable al crecer la base.

Los procedimientos almacenados pueden ofrecer esa frontera cuando se entiende su contenido y sus propietarios. La pregunta útil no es únicamente si una identidad conecta, sino qué lecturas y escrituras puede realizar por cada entrada autorizada.

Conceder la operación mediante un rol

El ejemplo crea una tabla de práctica con correos y un procedimiento que solo devuelve cantidad y suma. Usa una base desechable. GO separa lotes en el cliente; si el controlador no lo interpreta, envía cada lote por separado.

-- Run in a disposable practice database as its administrator.
CREATE TABLE dbo.PermissionInvoiceDemo (
    InvoiceId int PRIMARY KEY,
    CustomerEmail nvarchar(200) NOT NULL,
    Total decimal(12,2) NOT NULL
);
INSERT dbo.PermissionInvoiceDemo VALUES
(1, N'example1@example.invalid', 40.00),
(2, N'example2@example.invalid', 60.00);
GO
CREATE PROCEDURE dbo.GetInvoiceSummaryDemo
AS
BEGIN
    SET NOCOUNT ON;
    SELECT COUNT_BIG(*) AS InvoiceCount, SUM(Total) AS InvoiceTotal
    FROM dbo.PermissionInvoiceDemo;
END;
GO
CREATE ROLE InvoiceSummaryReaderDemo AUTHORIZATION dbo;
CREATE USER InvoiceReportUserDemo WITHOUT LOGIN;
ALTER ROLE InvoiceSummaryReaderDemo ADD MEMBER InvoiceReportUserDemo;
GRANT EXECUTE ON OBJECT::dbo.GetInvoiceSummaryDemo
TO InvoiceSummaryReaderDemo;

WITHOUT LOGIN crea deliberadamente un usuario para probar permisos localmente, no una cuenta de conexión. En el despliegue, crea o asocia el usuario real según el modelo de autenticación existente y añádelo al rol limitado.

El rol recibe EXECUTE sobre un procedimiento, sin SELECT general sobre la tabla. Ambos objetos comparten propietario mediante dbo y el procedimiento usa SQL estático. Con una cadena de propiedad intacta, SQL Server puede autorizar la llamada sin exigir por separado permisos sobre la tabla.

Se esperan dos facturas con total 100,00. Los correos no se proyectan. Esto muestra una frontera de acceso a objetos, no una garantía universal de privacidad: agregados sobre grupos pequeños también merecen revisión.

Entender dónde termina la protección

Un procedimiento no es seguro solo porque el llamador carezca de acceso directo. Nombres de objetos arbitrarios, SQL dinámico sin validar o resultados de todos los inquilinos pueden proporcionar capacidades excesivas. Revisa el cuerpo junto con el permiso concedido.

El SQL dinámico no aprovecha la misma suposición de cadena estática. sp_executesql con parámetros gestiona valores y reduce inyección, pero no concede automáticamente los permisos del texto generado. No resuelvas esa sorpresa convirtiendo la aplicación en db_owner.

Cuando hace falta acceso dinámico o entre fronteras, considera firma de módulos con alcance preciso o un contexto de ejecución elegido conscientemente. Firmar con certificado puede añadir permisos limitados durante la ejecución. El despliegue debe volver a firmar después de modificar el módulo. Mantén revisables el certificado y la capacidad exacta.

No habilites TRUSTWORTHY ni cadenas generales entre bases como reparación rutinaria. Cambian una frontera de confianza mucho mayor que una llamada. Diseña explícitamente la operación concreta entre bases.

Probar con la identidad de la aplicación

Un éxito bajo sysadmin demuestra poco sobre los permisos reales. Esta prueba de suplantación controlada ejecuta el resumen y restaura el contexto inicial incluso si falla.

EXECUTE AS USER = N'InvoiceReportUserDemo';
BEGIN TRY
    EXEC dbo.GetInvoiceSummaryDemo;
END TRY
BEGIN CATCH
    REVERT;
    THROW;
END CATCH;
REVERT;

Comprueba también que leer CustomerEmail directamente esté denegado. Prueba lo permitido y lo prohibido. Los GRANT del catálogo son insuficientes porque roles, permisos directos, DENY, propiedad y privilegios superiores modifican el acceso efectivo.

Separa identidad de despliegue e identidad de ejecución. Un despliegue puede crear o modificar procedimientos; las solicitudes normales no necesitan esa capacidad. Si una versión añade una operación, concédela deliberadamente en vez de ampliar el rol a todos los objetos actuales y futuros.

Revisa EXECUTE a nivel de esquema. Puede ser adecuado para un esquema de API gestionado explícitamente, pero también se aplica a procedimientos futuros. Es una decisión de gobierno, no solamente una sintaxis abreviada.

Incluye una comprobación útil en las entregas: operaciones admitidas funcionan, columnas protegidas no se leen directamente y objetos no pueden alterarse. Así una ampliación accidental de privilegios queda visible antes de convertirse en la configuración habitual.

Referencias técnicas: Microsoft Learn: Database Engine permissions · Microsoft Learn: GRANT object permissions · Microsoft Learn: Sign a procedure with a certificate.

Pregunta sobre este artículo

¿Tiene alguna pregunta sobre este tema?

Cuéntenos qué está evaluando o dónde tiene dificultades. Le responderemos con una recomendación práctica.

Inquiries are not enabled in this preview.

Hacer una pregunta sobre este artículo