sql >> Base de Datos >  >> RDS >> Sqlserver

Seguridad estricta de CLR en SQL Server 2017

¿Cómo puede un ensamblado CLR creado con PERMISSION_SET =SAFE acceder a recursos del sistema externo, llamar a código no administrado y adquirir privilegios de administrador del sistema?

Esto se debe a los cambios de seguridad realizados en .NET Framework, a partir de la versión 4.5 (creo).

La documentación de MSDN para Code Access Security Basics establece:

.NET Framework proporciona un mecanismo para la aplicación de distintos niveles de confianza en diferentes códigos que se ejecutan en la misma aplicación denominado Code Access Security (CAS). La seguridad de acceso al código en .NET Framework no debe usarse como un mecanismo para hacer cumplir los límites de seguridad basados ​​en el origen del código u otros aspectos de identidad. Estamos actualizando nuestra guía para reflejar que Code Access Security y Security-Transparent Code no se admitirán como un límite de seguridad con código de confianza parcial, especialmente código de origen desconocido. Recomendamos no cargar y ejecutar código de origen desconocido sin implementar medidas de seguridad alternativas.

Y luego apunta a la página de cambios de seguridad en .NET Framework que dice:

El cambio más importante en la seguridad de .NET Framework 4.5 está en la nomenclatura segura.

Lo que luego apunta a la documentación para Enhanced Strong Naming que dice:

Las claves de nombre seguro constan de una clave de firma y una clave de identidad. El ensamblado se firma con la clave de firma y se identifica con la clave de identidad. Antes de .NET Framework 4.5, estas dos claves eran idénticas. A partir de .NET Framework 4.5, la clave de identidad sigue siendo la misma que en versiones anteriores de .NET Framework, pero la clave de firma se mejora con un algoritmo hash más fuerte. Además, la clave de firma se firma con la clave de identidad para crear una contrafirma.

TAMBIÉN, la documentación de las Pautas de codificación segura establece:

La seguridad de acceso de código y el código transparente de seguridad no se admitirán como un límite de seguridad con código de confianza parcial. Recomendamos no cargar y ejecutar código de origen desconocido sin implementar medidas de seguridad alternativas...

Entonces, el modelo de seguridad para .NET cambió hace años, pero a SQL Server (hasta SQL Server 2017) se le ha permitido continuar usando el antiguo modelo de seguridad. Parece que, a partir de SQL Server 2017, se tomó la decisión de dejar de admitir el antiguo modelo de seguridad.

Sospecho que permitir el antiguo modelo de seguridad fue:

  • evitar que SQL Server (al menos la funcionalidad/los componentes relacionados con CLR) se base en las versiones más recientes de .NET Framework, y

  • responsable de la eliminación abrupta de SQLCLR como característica admitida de Azure SQL Database (la compatibilidad se agregó a fines de 2014 con el lanzamiento de v12, pero luego se eliminó por completo el 15 de abril de 2016).

Entonces, sí, esto apesta un poco. Lo que significa (al menos por el momento) es que uno necesita primero cree un certificado o una clave asimétrica (que se haya utilizado para firmar los ensamblajes que se cargarán) en [master] para luego crear un inicio de sesión desde y luego otorgar UNSAFE ASSEMBLY a ese inicio de sesión. Esta es la misma secuencia de eventos que uno debe hacer al cargar EXTERNAL_ACCESS y UNSAFE Ensambles, pero ahora, desafortunadamente, debe hacerse incluso para SAFE Asambleas.

Actualmente no existe ningún mecanismo para manejar esto de una manera completamente portátil (es decir, no depender de archivos externos) y no puede ser manejado por Visual Studio / SSDT sin intervención manual. Este ya era un poco el caso, pero al menos era posible crear una configuración para manejar esto de una manera completamente portátil (es decir, contenido completamente dentro de un script .sql):consulte Stairway to SQLCLR Level 7:Development and Security para obtener más detalles. (este es un artículo que escribí).

Es posible crear un certificado a partir de bytes hexadecimales (es decir, FROM BINARY = 0x... ) pero eso no funciona con Visual Studio (que se basa en MSBuild) / SSDT ya que el uso del Certificado requiere el uso de signtool y MSBuild usa sn .

Para que esto funcione de manera que funcione el proceso de publicación de Visual Studio / MSBuild / SSDT (lo que a su vez significaría que cualquiera podría crear un script .sql completamente autónomo capaz de crear la clave asimétrica sin depender de un archivo externo), el CREATE ASYMMETRIC KEY El comando debe mejorarse para permitir que se cree a partir de una cadena binaria. He hecho esta sugerencia en Microsoft Connect:permitir que se cree una clave asimétrica a partir de una cadena de bytes hexadecimales binarios como CREAR CERTIFICADO, así que apóyelo :-).

Alternativamente (por el momento, hasta que MS cree un método mejor, como mis sugerencias de clave asimétrica), puede probar cualquiera de las dos técnicas que describo en las siguientes publicaciones de blog (ambas funcionan completamente con SSDT):

  • SQLCLR frente a SQL Server 2017, Parte 2:"Seguridad estricta de CLR":solución 1
  • SQLCLR vs. SQL Server 2017, Parte 3:"Seguridad estricta de CLR" - Solución 2

Como última recurso, puede considerar el siguiente enfoque:

  1. TEMPORALMENTE establecer el [master] Base de datos para TRUSTWORTHY ON

    Para el siguiente paso (es decir, CREATE ASSEMBLY ) para ejecutar con éxito, el inicio de sesión que es el propietario de la base de datos (es decir, el mismo SID utilizado por [dbo] Usuario de [master] ) necesita tener el UNSAFE ASSEMBLY permiso. Si [master] es propiedad de sa o cualquier otro administrador de sistemas, entonces tiene todos los permisos y este requisito se ha cumplido. Pero, si [master] es propiedad de un inicio de sesión con pocos privilegios (una "práctica recomendada"), entonces deberá ejecutar la siguiente declaración para CREATE ASSEMBLY para trabajar cuando TRUSTWORTHY está ON :

    EXEC (N'USE [master]; GRANT UNSAFE ASSEMBLY TO [{DB_Owner_Login}];');
    
  2. Cree el ensamblado en [master]
  3. Cree la clave asimétrica a partir del ensamblaje
  4. Abandonar la Asamblea
  5. establecer el [master] Base de datos a TRUSTWORTHY OFF
  6. Crear el inicio de sesión desde la clave asimétrica
  7. Otorgar UNSAFE ASSEMBLY a ese inicio de sesión (esto reemplaza la necesidad de que la base de datos donde se carga el ensamblado se establezca en TRUSTWORTHY ON y para su propietario Inicie sesión para tener el UNSAFE ASSEMBLY permiso).

Tenga en cuenta que no incluya la nueva función "Montaje de confianza" como una opción aquí. La razón por la que no se mencionó se debe a que tiene muchos más defectos que beneficios, sin mencionar que, en primer lugar, es completamente innecesario dado que la funcionalidad existente ya manejó la situación que "Trusted Assemblies" debía abordar. Para obtener detalles completos sobre eso y una demostración de la forma correcta de manejar ensamblados sin firmar existentes, consulte:SQLCLR vs. SQL Server 2017, Parte 4:"Ensamblajes confiables":la decepción.