Riesgos de seguridad o rendimiento con SQL CLR [cerrado]

11

¿Existe algún riesgo particular de seguridad o rendimiento al usar el CLR en SQL Server?

SQLBen
fuente
No, el código SQLCLR no puede hacer nada más en una base de datos que un módulo de código T-SQL equivalente que se ejecute en el mismo contexto de seguridad. La prohibición ignorante de CLR también evita la implementación de SSISDB, lo que mejora drásticamente la seguridad a través de menos cuentas RDP, administración de FileSystem y menos necesidades de derechos, herencia de copia de seguridad dentro de los planes de mantenimiento, cifrado de paquete completo a través de TDE, por no mencionar las implementaciones y mantenimiento de paquetes SSIS a través de la sección de entorno del SSISDB y la falta de muchas funciones de C # en SSIS que requieren CLR.
Bryan Swan
1
He votado para reabrir esta pregunta porque creo que tiene cierta relevancia para la comunidad. La pregunta tal como está es válida, porque el nivel de entrada para un DBA en la configuración de seguridad de CLS es bastante alto. La respuesta bien escrita de @SolomonRutzky proporciona una buena introducción a la configuración de seguridad de CLR que Microsoft no proporciona en este nivel simplista.
John aka hot2use

Respuestas:

10

La pregunta, como señaló Remus, es demasiado genérica para obtener una respuesta, ya que la respuesta depende del contexto de qué funcionalidad se usará y cómo se usará.

En cuanto a "Seguridad":

Si está preguntando acerca de cualquier cosa que se pueda hacer en un ensamblaje marcado con PERMISSION_SET = SAFE, entonces no hay ningún problema que haya podido encontrar. Y SQLCLR es "más seguro" que usar xp_cmdshello los maravillosos procesos (eso fue sarcasmo) sp_OA*(o incluso Procedimientos almacenados extendidos, pero con suerte ya nadie está creando ninguno de esos).

Si desea un recorrido de lo que significa "SEGURO" en términos prácticos, consulte este artículo: Escalera a SQLCLR Nivel 3: Seguridad (Asambleas generales y SEGURAS) (se requiere registro gratuito).

Si está preguntando sobre cualquier cosa que se pueda hacer en un ensamblaje marcado con PERMISSION_SET = EXTERNAL_ACCESS, entonces ciertamente existen riesgos, de nuevo, dependiendo de qué funcionalidad se esté utilizando. Si escribe una rutina para leer directorios y nombres de archivos (es decir, solo lectura), entonces es solo una cuestión de lo que debe verse y no verse. Si está escribiendo código que permite eliminar un archivo, el riesgo aumenta. Pero lo que se puede hacer con esos recursos externos está controlado por:

  • si está utilizando o no suplantación:
    • no suplantación significa que el acceso a recursos externos se realiza a través de la cuenta "Iniciar sesión como" del servicio SQL Server. Independientemente de a qué tenga acceso esa cuenta, su función SQLCLR podrá hacerlo.
    • el uso de suplantación significa que el inicio de sesión en SQL Server que ejecuta la función, si ese inicio de sesión corresponde a un inicio de sesión de Windows, puede hacer lo que ese inicio de sesión de Windows en particular se le permite hacer. Si el inicio de sesión en SQL Server es un inicio de sesión de SQL Server, al intentar utilizar la suplantación se obtendrá un error.
  • Qué permisos se configuran en el recurso externo. Para el acceso al sistema de archivos, esto se controla a través de ACL en unidades NTFS.

Si está preguntando sobre algo que se puede hacer en un ensamblaje marcado con PERMISSION_SET = UNSAFE, eso es bastante abierto. Se considera que una gran cantidad de funcionalidades solo se pueden usar en ensamblajes INSEGUROS porque son cuestiones de estabilidad y / o comportamiento consistente más que seguridad o rendimiento. Por ejemplo, en un ensamblaje INSEGURO es posible tener una variable estática grabable. Por lo general, esto no es algo bueno ya que las clases SQLCLR se comparten en todas las sesiones. Si su intención es compartir datos en la memoria en todas las sesiones y ha planificado las condiciones de carrera (y ha realizado muchas pruebas), entonces debería estar bien ya que espera este comportamiento. Pero si simplemente deseaba que una variable estática grabable almacenara en caché un valor para una sesión en particular para no tener que buscarlo nuevamente o calcularlo nuevamente, y no sabía que otras sesiones están leyendo ese valor y posiblemente sobreescribiéndolo, bueno, Eso sería un problema.

Pero si le preocupa que alguien escriba en el Registro, pero aún no tiene ningún código que realmente escriba en el Registro, entonces probablemente no necesite preocuparse por esto ;-).

Si desea un recorrido de cómo EXTERNAL_ACCESS y UNSAFE funcionan en términos prácticos, y la diferencia entre establecer TRUSTWORTHY ON(no preferido) versus usar un inicio de sesión basado en clave o certificado asimétrico, consulte este artículo: Escalera al nivel 4 de SQLCLR: Seguridad (Asambleas EXTERNAS e INSEGURAS) (se requiere registro gratuito).

Con respecto al "rendimiento":

Todo esto es cuestión de lo que está tratando de hacer y cómo lo hace. Hay algunas cosas que son mucho más rápidas en SQLCLR, y algunas cosas que son más lentas. Pero al igual que con T-SQL, es posible realizar una tarea algo simple y / o eficiente y hacerla complicada y / o ineficiente haciendo las cosas incorrectamente. Pero el uso de SQL CLR no es inherentemente, por su propia naturaleza, más lento.

Solomon Rutzky
fuente
6

Asambleas SQLCLR se pueden instalar con tres niveles de acceso de seguridad: SAFE | EXTERNAL_ACCESS | UNSAFE. Esto está ampliamente documentado, consulte CREATE ASSEMBLYy Diseño de ensamblajes :

Administración de la seguridad de ensamblado
Puede controlar cuánto puede acceder un ensamblado a los recursos protegidos por .NET Code Access Security cuando ejecuta código administrado. Para ello, especifique uno de los tres conjuntos de permisos cuando cree o modifique un ensamblaje: SAFE, EXTERNAL_ACCESS o UNSAFE.

SAFE
SEGURO es el conjunto de permisos predeterminado y es el más restrictivo. El código ejecutado por un ensamblado con permisos SAFE no puede acceder a recursos externos del sistema, como archivos, la red, variables de entorno o el registro. El código SAFE puede acceder a los datos de las bases de datos locales de SQL Server o realizar cálculos y lógica empresarial que no implican acceder a recursos fuera de las bases de datos locales.
La mayoría de los ensamblados realizan tareas de computación y administración de datos sin tener que acceder a recursos fuera de SQL Server. Por lo tanto, recomendamos SAFE como conjunto de permisos de ensamblaje.

EXTERNAL_ACCESS
EXTERNAL_ACCESS permite que los ensamblados accedan a ciertos recursos externos del sistema, como archivos, redes, servicios web, variables ambientales y el registro. Solo los inicios de sesión de SQL Server con permisos de ACCESO EXTERNO pueden crear ensamblados EXTERNAL_ACCESS. Los ensamblados SAFE y EXTERNAL_ACCESS solo pueden contener código que sea verificablemente seguro para escribir. Esto significa que estos ensamblajes solo pueden acceder a clases a través de puntos de entrada bien definidos que son válidos para la definición de tipo. Por lo tanto, no pueden acceder arbitrariamente a las memorias intermedias que no son propiedad del código. Además, no pueden realizar operaciones que puedan tener un efecto adverso sobre la solidez del proceso de SQL Server.

UNSAFE
UNSAFE brinda a los ensamblados acceso sin restricciones a los recursos, tanto dentro como fuera de SQL Server. El código que se ejecuta desde un ensamblaje INSEGURO puede llamar a código no administrado. Además, especificar UNSAFE permite que el código en el ensamblaje realice operaciones que el verificador CLR considera inseguras de tipo. Estas operaciones pueden acceder potencialmente a las memorias intermedias en el espacio de proceso de SQL Server de manera incontrolada. Los ensamblados INSEGUROS también pueden potencialmente subvertir el sistema de seguridad de SQL Server o Common Language Runtime. Los permisos NO SEGUROS deben ser otorgados solo a ensamblados altamente confiables por desarrolladores o administradores experimentados. Solo los miembros de la función fija de servidor sysadmin pueden crear ensamblados INSEGUROS.

Existen más restricciones sobre los atributos CLR permitidos y solo se admite un subconjunto de los ensamblados de .Net Framework. Nuevamente, consulte la documentación vinculada.

En cuanto al rendimiento, lo más importante es recordar que SQL Server es un entorno cooperativo multitarea, mientras que CLR no lo es. El código SQLCLR debe llamar en Thread.BeginThreadAffinity()cualquier momento que acapare la CPU por cualquier duración (incluido el bloqueo). Adam Machanic tiene una excelente presentación sobre el tema, ver Datos, más rápido: Técnicas de rendimiento de Microsoft SQL Server con SQLCLR .

El tema es vasto y la pregunta vaga. SQLCLR puede realizar algunas tareas únicas que ninguna otra característica puede igualar. Y SQLCLR es solo otra arma en el arsenal de SQL Server con el que puedes dispararte en el pie, con rendimiento o seguridad. Lee la documentación.

Remus Rusanu
fuente
Gracias por esto Remus. Sé que la pregunta es vaga, pero ¿hay algún problema de seguridad al respecto? gracias
SQLBen