ciberseguridad

Contextos de seguridad en SQL dinámico: permisos, procedimientos y sp_executesql

En mi artículo anterior os hablé de cómo construir SQL dinámico de forma segura usando sp_executesql, y cómo evitar riesgos como el SQL Injection. Sin embargo, hay un aspecto igual de crítico que no se suele tener en cuenta: el contexto de seguridad desde el que se ejecuta el código dinámico y su impacto en los permisos.

Muchos desarrolladores se sorprenden cuando un procedimiento almacenado que funciona con SQL «normal» deja de funcionar al pasar a SQL dinámico, a pesar de tener los mismos permisos. El motivo está en cómo SQL Server maneja los permisos de ejecución implícitos y qué ocurre cuando usamos sp_executesql. En este artículo voy a tratar de explicarlo paso a paso.

Permisos implícitos al ejecutar un procedimiento almacenado

Cuando concedemos a un usuario permiso para ejecutar un procedimiento almacenado, por ejemplo:

Ese usuario puede ejecutar el procedimiento sin necesidad de tener permisos directos sobre las tablas internas que use dicho procedimiento. Es decir, aunque no tenga SELECT sobre Sales.SalesOrderHeader, si el procedimiento ejecuta esta consulta:

… el usuario podrá obtener los datos. Esto ocurre porque el contexto de ejecución del procedimiento es el del propietario, y si el procedimiento y las tablas tienen el mismo dueño, SQL Server permite ese acceso mediante el mecanismo de ownership chaining (encadenamiento de propiedad). Este comportamiento es clave para encapsular la lógica de negocio sin exponer directamente las tablas subyacentes.

¿Qué ocurre con los permisos cuando usamos SQL dinámico?

Aquí viene la trampa. Si dentro del procedimiento usamos SQL dinámico con sp_executesql como:

… entonces se rompe la cadena de propiedad, y SQL Server evalúa los permisos como si el usuario estuviera ejecutando directamente la consulta, no como si formara parte del procedimiento. En otras palabras: aunque el usuario tenga permiso de ejecución sobre el procedimiento, necesitará permisos explícitos de SELECT sobre la tabla referenciada en el SQL dinámico.

Esto puede llevar a errores difíciles de diagnosticar si no se comprende cómo funciona el contexto de seguridad.

Demostración del problema de permisos

Imaginemos este escenario:

  • Usuario app_user
  • Procedimiento dbo.usp_Informe
  • Tabla Sales.SalesOrderHeader
  • Escenario app_user tiene EXECUTE sobre usp_Informe, pero no SELECT sobre la tabla
  • Código del procedimiento:

El primer SELECT se ejecuta correctamente gracias al ownership chaining. El segundo da error:

Cuándo se rompe y cuándo no

Para que se mantenga el ownership chaining, se deben cumplir dos condiciones:

  • Los objetos deben pertenecer al mismo propietario (normalmente dbo)
  • La consulta no debe usar SQL dinámico
  • En cuanto usamos EXEC, sp_executesql o EXECUTE AS con un contexto diferente, se interrumpe esa cadena y SQL Server valida los permisos del usuario directamente.

¿Cómo se soluciona el problema de permisos?

Existen varias estrategias según el contexto, pero las más comunes son estas:

1. Firmar el procedimiento con un certificado

Es la solución más profesional. Se firma el procedimiento con un certificado que tenga los permisos necesarios sobre las tablas, y el usuario ejecuta el procedimiento sin tener permisos directos. Requiere más trabajo, pero es la solución más segura y escalable, especialmente en entornos regulados o críticos.

2. Conceder permisos explícitos sobre las tablas

Es la opción más directa pero rompe el aislamiento que buscamos al encapsular la lógica dentro de procedimientos. Puede ser válido en entornos internos o controlados.

Pero en ese caso ya no protegemos las tablas detrás de la lógica del procedimiento.

3. Evitar usar SQL dinámico innecesariamente

Si el acceso a los datos no requiere construir partes dinámicas (columnas, nombres de tabla, filtros condicionales avanzados), es mejor mantener el SQL como texto plano. Así se conserva el contexto de permisos del procedimiento.

En ocasiones, usamos SQL dinámico cuando lo que realmente necesitamos es ejecutar una u otra consulta en función de un parámetro de entrada del procedimiento. En estos casos es mejor crear una lógica con IF que códigos dinámicos. 

Por ejemplo, este procedimiento con código SQL dinámico:

… lo podríamos sustituir por este:

Conclusión

El uso de SQL dinámico no es solo una cuestión de sintaxis o seguridad frente a inyecciones. También tiene implicaciones directas en el modelo de permisos y seguridad de SQL Server. Es importante entender que al usar sp_executesql, el procedimiento pierde la protección que le daba la cadena de propiedad, y el motor evalúa los permisos como si se tratase de una ejecución independiente. Este comportamiento puede ser confuso si no se conoce, pero una vez lo interiorizamos, se convierte en una herramienta poderosa para diseñar arquitecturas seguras y mantenibles. Si estamos diseñando procedimientos que deben proteger las tablas subyacentes, debemos considerar firmar con certificados, controlar cuidadosamente los permisos, o bien evitar SQL dinámico cuando sea posible.  

En el artículo anterior explicamos cómo generar SQL dinámico de forma segura desde el punto de vista sintáctico y de rendimiento. Pero ahora, sabemos que también hay que hacerlo de forma segura desde el punto de vista del contexto de ejecución.

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima! 

Publicado por Roberto Carrancio en Cloud, SQL Server, 0 comentarios

Código dinámico con seguridad en SQL Server

En muchas ocasiones nos enfrentamos a escenarios donde necesitamos construir sentencias SQL de forma dinámica. Ya sea para crear filtros condicionales, construir cláusulas ORDER BY en tiempo de ejecución o ejecutar consultas sobre distintos objetos, la generación de SQL dinámico parece una solución sencilla y flexible. Pero esta potencia viene acompañada de riesgos, especialmente desde el punto de vista de la seguridad.

A lo largo de los años, he visto cómo el uso descuidado del SQL dinámico ha sido uno de los vectores de ataques de inyección SQL (SQLi) más comunes, y aún sigue siéndolo. Por eso, en este artículo vamos a repasar cómo generar SQL dinámico en SQL Server de forma segura, analizando técnicas recomendadas y errores frecuentes, con ejemplos claros y aplicables.

¿Cuándo usamos SQL dinámico?

Los escenarios más frecuentes en los que aparece la necesidad de SQL dinámico suelen estar relacionados con filtros condicionales, búsquedas avanzadas, generación de informes personalizables, lógica multi-tenant o incluso mantenimiento automatizado.

Un ejemplo muy habitual es una búsqueda con varios filtros opcionales. Supongamos una aplicación que consulta una tabla de personas donde el usuario puede buscar por nombre, ciudad y país. Si tratamos de resolver esto con un procedimiento estándar, el número de combinaciones posibles puede crecer exponencialmente. El SQL dinámico permite construir la sentencia ajustada a los filtros que el usuario haya proporcionado.

El problema del SQL Injection

El gran riesgo del SQL dinámico mal implementado es el conocido SQL Injection, una técnica con la que un atacante puede alterar la consulta ejecutada para acceder o modificar datos sin autorización. Esto ocurre cuando concatenamos directamente valores dentro de la cadena SQL. Veamos un ejemplo inseguro:

Si @city proviene de un parámetro externo (una app, una web), el usuario podría inyectar algo como: “Madrid’; DROP TABLE Person.Person;” y provocar un desastre.

Este patrón, por desgracia, sigue viéndose demasiado a menudo en aplicaciones heredadas o mal diseñadas.

Uso seguro de SQL dinámico con sp_executesql

La solución más eficaz ante este problema es usar sp_executesql, que permite construir consultas dinámicas pero separando el código de los datos mediante parámetros tipados. Esto bloquea cualquier intento de inyección porque el valor del parámetro no se interpreta como código. Reescribamos el ejemplo anterior de forma segura:

Aquí, aunque el usuario intentase inyectar código en @city, no lo conseguiría. SQL Server lo tratará como un valor, no como una parte de la instrucción.

Además, esta técnica también permite la reutilización de planes de ejecución, lo que supone una ventaja adicional en términos de rendimiento.

Código dinámico con filtros condicionales

Un paso más allá es cuando necesitamos construir dinámicamente múltiples filtros. En estos casos, lo ideal es ir concatenando las condiciones SQL pero parametrizando todos los valores. Veamos un ejemplo más completo:

De este modo, solo se añaden los filtros que tengan valor, pero todos los valores siguen protegidos mediante parámetros.

Identificadores dinámicos: el caso más delicado

sp_executesql no permite parametrizar nombres de columnas o tablas. Esto es especialmente importante si necesitamos cambiar el objeto sobre el que se ejecuta la consulta. En estos casos debemos concatenar el identificador, pero asegurándonos de que el valor es válido. La función QUOTENAME es clave para evitar inyecciones sobre identificadores ya que introduce el nombre del objeto entre corchetes [].

Aquí estamos asumiendo que el nombre de la tabla ha sido validado previamente. Aún así, QUOTENAME evita que un valor como SalesOrderHeader; DROP TABLE x;– pueda hacer daño. 

En entornos multi-tenant esto es especialmente útil si cada cliente tiene su propia tabla (modelo database-per-tenant) y accedemos a ellas dinámicamente.

Consejos adicionales para SQL dinámico seguro

Cuando usamos SQL dinámico en entornos críticos o expuestos a usuarios externos, es fundamental aplicar otras prácticas complementarias como encapsular en procedimientos almacenados ya que así reducimos la exposición del motor y permitimos auditar más fácilmente. Otra buena práctica es registrar las consultas generadas, esto es especialmente útil para soporte, auditoría y detección de patrones de abuso. Otro paso obligatorio, para mi es evitar privilegios excesivos; el usuario que ejecuta el código dinámico no debe tener más permisos de los necesarios.

Por último, si queremos ir un paso más allá, podemos aplicar SET FMTONLY OFF y otras opciones de seguridad sobre todo si trabajamos con herramientas de terceros. De esta manera podremos asegurarnos de que el motor de base de datos ejecuta todo el bloque tal cual, sin modificar el flujo por culpa del modo de metadatos.

Conclusión

El SQL dinámico en SQL Server puede ser tan útil como peligroso. En nuestras manos está la diferencia entre construir una solución flexible y robusta o abrir una puerta trasera a posibles ataques.

La clave está en nunca concatenar valores directamente y utilizar sp_executesql con parámetros siempre que sea posible. Cuando se trabaja con nombres de objetos, debemos validar y proteger con QUOTENAME. Y si el contexto lo permite, encapsular toda la lógica dentro de procedimientos controlados.

Estas técnicas yo las aplico habitualmente en proyectos reales, y son parte esencial de una arquitectura segura, especialmente en entornos donde la escalabilidad o la “multi-tenencia” requieren cierta flexibilidad a nivel de metadatos. 

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima! 

Publicado por Roberto Carrancio en Cloud, SQL Server, 1 comentario

Fin del soporte de SQL Server 2019: ¿Qué Significa?¿Qué Cambia?

El pasado viernes 28 de febrero de 2025 marcó un hito en la historia de SQL Server 2019: finalizó su soporte estándar. Aunque todavía queda el soporte extendido hasta el 8 de enero de 2030, este cambio tiene implicaciones significativas para las empresas que aún dependen de esta versión. Además, el jueves 27 de febrero se lanzó la última Cumulative Update (CU32) para SQL Server 2019, lo que significa que ya no habrá más actualizaciones regulares para esta versión.

En este artículo, quiero aprovechar esta noticia para explicar las diferencias entre el soporte estándar y extendido, y además veremos qué implica la última CU, y analizaremos las características que han desaparecido oficialmente con SQL Server 2019.

Diferencias entre el soporte estándar y el soporte extendido

Como norma general, Microsoft ofrece dos niveles de soporte para sus productos empresariales, el soporte estándar y el soporte extendido. Cada uno tiene un propósito diferente y afecta la forma en que las empresas deben gestionar sus sistemas.

Soporte estándar: Actualizaciones y asistencia completa

El soporte estándar, que terminó el 28 de febrero de 2025 para SQL Server 2019, es el más completo y proporciona actualizaciones completas, soporte y mejoras. 

Durante este período, Microsoft lanza regularmente actualizaciones de seguridad y funcionalidad que corrigen vulnerabilidades y mejoran el rendimiento del software.

En lo relativo al soporte técnico, se ofrece asistencia gratuita por parte de Microsoft a través de distintos canales, incluyendo documentación.

Además, se publican Service Packs y Cumulative Updates con mejoras significativas en compatibilidad y rendimiento.

En resumen, durante este tiempo de soporte estándar, cualquier incidencia puede ser reportada y Microsoft trabaja activamente en resolver errores críticos y mejorar el rendimiento.

Soporte extendido: Solo parches de seguridad

A partir de ahora, SQL Server 2019 entra en la fase de soporte extendido, que dura hasta el 8 de enero de 2030. Este periodo implica cambios importantes en las actualizaciones y soporte, aunque no desaparezcan del todo.

Por ejemplo, no habrá más mejoras de funcionalidad. Las únicas actualizaciones serán parches de seguridad críticos.

En relación con el soporte técnico, la asistencia por parte de Microsoft ya no es gratuita y requiere un contrato especial.

Además, a partir de este punto ya no se garantizarán ajustes para nuevas versiones de Windows Server o entornos en la nube, es decir, la compatibilidad pasa a ser limitada.

Para las empresas que aún dependen de SQL Server 2019, esto significa que deben considerar seriamente una migración a una versión más reciente, como SQL Server 2022 o Azure SQL, para garantizar la seguridad y estabilidad de sus bases de datos.

Última Cumulative Update para SQL Server 2019

Un dia antes del fin de soporte estándar, el jueves 27 de febrero de 2025, Microsoft lanzó la última Cumulative Update (CU32) para SQL Server 2019. Es un paquete de actualización que incluye correcciones de errores, optimizaciones de rendimiento y mejoras de seguridad. Sin embargo, ahora que el soporte estándar ha terminado, no habrá más CUs regulares para SQL Server 2019.

Las empresas deben asegurarse de aplicar esta última actualización lo antes posible para garantizar que su entorno SQL Server 2019 esté en la mejor condición posible antes de entrar en la fase de soporte extendido.

Características eliminadas en SQL Server 2022

Con la llegada de SQL Server 2022, Microsoft ha eliminado algunas funcionalidades que habían sido introducidas en versiones anteriores pero que no lograron una adopción significativa. La más notable es Big Data Cluster (BDC), una solución que permitía la integración de SQL Server con entornos de big data basados en Kubernetes.

Adiós a Big Data Cluster

5 años ha durado esta característica que introdujo SQL Server 2019. La idea era buena, una solución para ejecutar cargas de trabajo analíticas en clústeres de datos distribuidos con tecnologías como Spark y HDFS. Sin embargo, con SQL Server 2022, Microsoft ha descontinuado esta característica, lo que significa que ya no hay soporte oficial para BDC. No hace falta hacer muchas conjeturas, el enemigo estaba en casa con las soluciones en la nube que Microsoft comercializa con las mismas funciones que BCD.

Por tanto, las empresas que aún dependen de Big Data Cluster deben considerar alternativas como Azure Synapse Analytics que ofrece capacidades similares para análisis de grandes volúmenes de datos, Apache Spark en Azure Databricks para entornos que necesitan procesamiento distribuido y Data Lake en Azure como repositorio de datos escalable. O, la solución más sencilla, Microsoft Fabric, con todas esas funcionalidades integradas en un mismo sistema.

¿Qué deben hacer las empresas ahora?

Con el fin del soporte estándar de SQL Server 2019 y la eliminación de características clave en SQL Server 2022, las organizaciones deben tomar decisiones estratégicas para sus entornos de base de datos. 

En primer lugar hay que aplicar la última CU de SQL Server 2019. Mientras se plantean otras opciones es clave asegurarse de que el sistema esté en la versión más reciente antes de la fase de soporte extendido.

Una vez con SQL Server con la CU 32 es el momento de evaluar una actualización a SQL Server 2022 o migrar a Azure para continuar recibiendo soporte completo y acceder a nuevas funcionalidades. Si la infraestructura lo permite, mover cargas de trabajo a la nube puede ser una opción atractiva pero, si deseamos (o necesitamos) continuar en entornos locales SQL Server 2022 es la única opción posible.

Por último, si estás utilizando Big Data Cluster es momento de comparar las alternativas en las opciones que nos da Microsoft en Azure o Fabric.

Conclusión

El fin del soporte estándar de SQL Server 2019 marca un punto de inflexión para muchas empresas. Aunque todavía quedan casi cinco años de soporte extendido, la falta de actualizaciones de funcionalidad y el coste del soporte técnico pueden hacer que la actualización a SQL Server 2022 o la migración a Azure SQL sea la mejor opción. Además, la desaparición de Big Data Cluster confirma la tendencia de Microsoft de enfocarse en soluciones más modernas en la nube para el análisis de grandes volúmenes de datos.

Es el momento ideal para planificar una estrategia de actualización y asegurarse de que la infraestructura de bases de datos esté preparada para el futuro.

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

Publicado por Roberto Carrancio en Cloud, Rendimiento, SQL Server, 0 comentarios

Permisos en SQL con grupos de AD y roles de SQL Server

La gestión de permisos en SQL Server es un aspecto fundamental para garantizar la seguridad y el acceso controlado a los datos. En entornos empresariales, lo más eficiente es utilizar grupos de Active Directory (AD) junto con roles en SQL Server para simplificar la administración y reducir la carga de trabajo asociada a la asignación individual de permisos.

Además, con la evolución de la gestión de identidades en la nube, Microsoft Entra ID (antes Azure AD) nos da la posibilidad de utilizar grupos de seguridad automáticos, lo que facilita aún más la administración de accesos en SQL Server y Azure SQL Database. En este artículo, vamos a ver como cómo combinar estas tecnologías para una gestión eficiente y segura de los permisos en SQL Server.

Uso de grupos de Active Directory en SQL Server

Cuando gestionamos el acceso a una base de datos SQL en un entorno corporativo, es una mala práctica asignar permisos directamente a usuarios individuales. En su lugar, la mejor estrategia es utilizar grupos de seguridad de Active Directory.

¿Por qué? Porque la asignación de permisos a nivel usuario no solo es más costosa sino que también más propensa a errores. Una vez que has asignado y validado los permisos a un grupo ya solo deberás añadir o quitar usuarios a ese grupo. Esto facilita enormemente tanto el alta como la baja de usuarios y permite reutilizar los grupos por los distintos servidores SQL Server de la empresa.

Creación de grupos de AD

Para una gestión correcta se pueden crear diferentes grupos en Active Directory, como por ejemplo:

  • DB_Admins: Administradores de la base de datos.
  • DB_ReadOnly: Usuarios con solo lectura.
  • DB_Editors: Usuarios con permisos de modificación.
  • DB_Backups: Grupo con permisos para realizar copias de seguridad.

Estos grupos están muy simplificados y seguramente en tu entorno empresarial debas crear bastantes más. Aquí no hay una solución correcta para todas las empresas y dependerá de tus necesidades, hay quien crea los grupos por departamento, servicio, servidor o una combinación de estos factores. Sin embargo, una de las buenas prácticas que he aplicado en estos ejemplos es seguir una nomenclatura estandarizada. Si te fijas, querido lector, todos mis grupos empiezan por DB_ lo que hace más sencillo localizarlos en el directorio activo y, de un simple vistazo, saber su finalidad. Te recomiendo combinar una nomenclatura estándar con el uso de unidades organizativas de Active Directory.

Asignación de permisos a los grupos de AD en SQL Server

Una vez creados los grupos en AD, podemos agregarlos a SQL Server y asignarles roles adecuados.

De este modo, cualquier usuario añadido al grupo de AD DB_ReadOnly tendrá acceso de solo lectura a la base de datos sin necesidad de configurar permisos individualmente en SQL Server.

Mantenimiento de accesos

La ventaja de este enfoque es que los administradores pueden gestionar accesos desde Active Directory sin necesidad de tocar SQL Server. Por ejemplo, si un empleado cambia de departamento y ya no debe acceder a la base de datos, basta con eliminarlo del grupo de AD correspondiente y no hay que tocar nada en los servidores SQL Server. Además, estos grupos también pueden llevar asociados otros permisos a nivel recursos de red como directorios compartidos o acceso a equipos.

Gestión de permisos con roles de SQL Server

SQL Server proporciona roles que permiten agrupar permisos y facilitar la administración. Podríamos decir que es el equivalente a los grupos de AD pero dentro de SQL Server. La particularidad de estos roles es que pueden ser de dos tipos, a nivel de servidor o a nivel de base de datos. 

Los roles de servidor permiten asignar permisos globales dentro de SQL Server que afecten a tareas relacionadas con la instancia como sysadmin que da acceso total, securityadmin que permite gestionar accesos y permisos, dbcreator que permite crear y modificar bases de datos o public que es el rol básico asignado a todos los logins y permite la conexión a la instancia. Un ejemplo de asignación de un grupo de AD a un rol de servidor:

Los roles a nivel de base de datos, como su propio nombre indica, se crean dentro de cada base de datos. Podemos crear nuestros propios roles o usar los roles predefinidos. Estos roles predefinidos son los que trae ya la base de datos y gestionan los permisos básicos. Tenemos db_owner para otorgar control total sobre la base de datos, db_datareader que permite leer los datos, db_datawriter que permite insertar, actualizar y eliminar datos y db_ddladmin que otorga la capacidad de modificar esquemas y objetos. 

Ejemplo de asignación de un grupo de AD a un rol de base de datos:

Además de los roles predefinidos, podemos crear roles personalizados para necesidades específicas. Es muy común, por ejemplo, necesitar los accesos solo para determinados esquemas y no toda la base de datos y, en ese caso ya no podremos usar roles predefinidos. Para crear un rol personalizado, asignar permisos y añadir miembros usaremos:

Grupos de seguridad automáticos en Entra ID

No quería cerrar este artículo sin hablar de los grupos de Entra ID (Azure Active Directory)

que básicamente es el equivalente a Active Directory en la nube de Azure. Igual que en Active directory en Entra ID vamos a poder crear grupos para asignar a nuestros usuarios y que puedan iniciar sesión en Azure SQL y Azure SQL Database además de en los SQL Server locales gracias a la integración con Azure ARC. 

Una de las ventajas que ha introducido Entra ID son los grupos de seguridad dinámicos y automáticos, lo que permite gestionar accesos sin intervención manual. Estos grupos pueden usarse para SQL Server y Azure SQL Database como hemos vistos antes y, especialmente, en entornos híbridos donde se combinan identidades locales y en la nube.

Creación de grupos dinámicos en Entra ID

Desde el portal de Entra ID, se puede configurar un grupo dinámico basado en reglas. Realmente es como un grupo normal solo que los miembros se van a añadir en base a unas reglas que definamos sobre sus propiedades. Por ejemplo, para asignar automáticamente usuarios al grupo SQL_ReadOnly si pertenecen al departamento de Finanzas:

  1. Iremos a Entra ID > Grupos y seleccionaremos Nuevo grupo.
  2. En “Tipo de grupo” elegiremos “Seguridad”
  3. En “Asignación de miembros” marcaremos la opción “Asignación dinámica de usuarios”.
  4. Aquí ya podremos definir nuestra regla, en este caso “user.department -eq «Finance»”
  5. Por último podremos hacer ya la asignación del grupo de Entra ID a SQL Server.

En Azure SQL Managed Instance o bases de datos en Azure, podemos usar Entra ID para autenticación y gestión de permisos:

Esto permite que los usuarios asignados automáticamente al grupo SQL_ReadOnly en Entra ID obtengan acceso sin intervención manual.

Ventajas de este enfoque

Como hemos visto antes, administrar permisos desde Active Directory reduce la complejidad de SQL Server y evita errores humanos al configurar accesos manualmente. Si ya lo sincronizamos con Entra ID nos permite una centralización total de la seguridad. Si hay cambios en la organización, basta con modificar los grupos en AD o Entra ID sin necesidad de tocar SQL Server. A mayores, el acceso se gestiona de manera consistente y auditable desde un único punto de control lo que minimiza riesgos de accesos indebidos.

Además con Entra ID, los permisos pueden gestionarse tanto para SQL Server on-premises como para Azure SQL, facilitando la migración a la nube y otorgando al usuario un inicio de sesión único (single sign-on) que le hará las cosas mucho más sencillas.

Conclusión

El uso de grupos de Active Directory y roles de SQL Server proporciona una forma eficiente de gestionar permisos en bases de datos. La integración con Entra ID y sus grupos de seguridad dinámicos añade una capa adicional de automatización y control, ideal para entornos híbridos o en la nube. Si implementamos estas estrategias, podemos lograr una administración más segura, flexible y escalable, reduciendo la carga administrativa y mejorando el control de accesos a nuestros datos en SQL Server.

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima! 

Publicado por Roberto Carrancio en Cloud, SQL Server, 0 comentarios

Always On Availability Groups sin WSFC

Always On Availability Groups (AG) es una funcionalidad avanzada de SQL Server que proporciona alta disponibilidad, recuperación ante desastres y replicación. Tradicionalmente, esta tecnología se implementa utilizando Windows Server Failover Cluster (WSFC). Sin embargo, existe una alternativa que elimina la dependencia de WSFC, simplificando la infraestructura en ciertos entornos y adaptándose mejor a escenarios específicos. En este artículo, y a raíz de una petición vuestra en un comentario a uno de mis videos en youtube, os explicaré cómo configurar AG en Windows sin cluster, sus características, limitaciones y casos de uso, además de los scripts necesarios para su administración.

Introducción a Always On sin WSFC

La configuración de Always On sin WSFC, también conocida como grupos de Disponibilidad de Escala de Lectura (Read-Scale Availability Groups, RSAG), es ideal en entornos donde no es posible o necesario implementar un cluster. Esta arquitectura, disponible desde SQL Server 2017, permite que las réplicas de SQL Server funcionen de manera independiente, conectándose directamente entre sí para mantener la sincronización de los datos. A diferencia de la configuración tradicional, no existe una gestión centralizada del Quórum ni un mecanismo de failover automático. En su lugar, los DBA asumimos un papel activo en la supervisión, configuración y administración de los failovers, listeners y otros elementos. Aunque este modelo elimina parte de la complejidad asociada a los clusters, también requiere conocimientos avanzados para garantizar un funcionamiento eficiente y seguro.

Características de Always On sin WSFC

La autonomía de las réplicas es una de las principales características de esta configuración. Cada instancia de SQL Server opera de forma independiente y no depende de un cluster subyacente para coordinar sus roles. El failover, por otro lado, debe realizarse manualmente o mediante scripts personalizados, lo que otorga flexibilidad pero requiere una monitorización constante. Los listeners, que en un entorno con WSFC se configuran automáticamente, aquí deben implementarse manualmente utilizando soluciones externas como balanceadores de carga o DNS, lo que puede agregar complejidad operativa.

En términos de sincronización, esta configuración solo admite el modo asíncrono, lo que prioriza el rendimiento pero, sumado a la falta de balanceo automático, descarta su uso como solución de alta disponibilidad para todos los escenarios. Además, aunque al eliminar la necesidad de WSFC, la infraestructura se simplifica, reduciendo los costes asociados sigue siendo necesario licenciar ambas instancias con una edición Enterprise lo que eleva los costes.

Ventajas y Limitaciones

La eliminación del cluster de Windows en esta configuración aporta beneficios significativos, como la reducción de costes al no requerir licencias adicionales ni configuraciones complejas asociadas a WSFC. Esto hace que sea una solución atractiva para entornos de pruebas y desarrollo. Además, la autonomía de las réplicas facilita la implementación en sistemas más simples, evitando la necesidad de depender de un cluster para mantener la alta disponibilidad.

Sin embargo, esta configuración también tiene limitaciones importantes. La ausencia de un mecanismo de quorum aumenta el riesgo de situaciones de split-brain (ocurre cuando uno o más nodos de un clúster experimentan la desconexión de los otros nodos, lo que resulta en la formación de subclústeres), especialmente en escenarios donde no se monitoriza adecuadamente el estado de las réplicas. Por otro lado, la falta de un listener nativo complica la integración con aplicaciones que dependen de un punto de acceso único para conectarse al nodo activo. La escalabilidad también es más limitada en comparación con un entorno gestionado por WSFC, lo que la hace menos adecuada para infraestructuras complejas o con muchos nodos.

Casos de Uso

Always On sin cluster en Windows es una solución especialmente útil en entornos de pruebas y desarrollo, donde la alta disponibilidad no es crítica pero la replicación de datos es necesaria para realizar simulaciones y validaciones. También es una opción adecuada para aquellos escenarios que no requieren failover automático, pero necesitan una forma de mantener datos sincronizados entre varias instancias para dividir las cargas de trabajo, por ejemplo replicas de solo lectura para análisis en tiempo real.

En sistemas autónomos, donde las réplicas pueden operar independientemente, esta arquitectura también encuentra un buen uso. Asimismo, es una alternativa viable cuando se dispone de soluciones externas avanzadas, como balanceadores de carga o gestión de DNS, que pueden mitigar las limitaciones asociadas a la falta de listeners nativos.

Configuración de Always On sin WSFC

La configuración comienza habilitando Always On en cada instancia de SQL Server desde el Configuration Manager, asegurándose de que las bases de datos estén en modo de recuperación completa. Los endpoints deben configurarse manualmente en cada réplica para permitir la comunicación entre ellas. Una vez configurados los endpoints, se procede a crear el grupo de disponibilidad desde la réplica primaria utilizando T-SQL, definiendo las bases de datos y réplicas participantes, junto con sus modos de sincronización.

En las réplicas secundarias, las bases de datos deben restaurarse en modo de recuperación incompleta (NORECOVERY) antes de añadirlas al grupo de disponibilidad. Finalmente, los listeners deben configurarse manualmente si es necesario, ya sea mediante un DNS dedicado o un balanceador de carga externo, lo que permite redirigir el tráfico al nodo activo.

Gestión y Scripts de Administración

La administración de Always On sin WSFC depende en gran medida de scripts personalizados ya que no dispondremos del dashboard de Always On. Por ejemplo, el estado de sincronización de las réplicas puede verificarse con consultas a las vistas dinámicas sys.dm_hadr_database_replica_states. Además, algunas columnas de esta DMV relacionadas con el clúster pueden mostrar datos sobre un clúster predeterminado interno. Estas columnas son solo para uso interno y se pueden ignorar.

El failover manual, que es una tarea común en esta configuración, se realiza utilizando el comando ALTER AVAILABILITY GROUP … FAILOVER. Además, tras un failover, es necesario reanudar las bases de datos en la nueva réplica primaria con el comando ALTER DATABASE … SET HADR RESUME.

Conclusión

Always On Availability Groups sin cluster en Windows es una alternativa poderosa para entornos específicos, especialmente aquellos donde los costes o la complejidad de WSFC no son aceptables. Aunque su implementación y administración requieren habilidades avanzadas y mayor supervisión, esta configuración ofrece flexibilidad y simplicidad en infraestructura, siendo especialmente adecuada para entornos de pruebas, desarrollo y réplicas de solo lectura. Sin embargo, su uso en producción debe evaluarse cuidadosamente, teniendo en cuenta sus limitaciones en términos de Quórum, failover automático y escalabilidad.

Con una correcta planificación y monitorización, esta arquitectura puede proporcionar una solución eficaz para mantener datos sincronizados en escenarios específicos. Si se implementa correctamente, Always On sin cluster puede ser un recurso invaluable para arquitecturas modernas y simplificadas.

Te invito a seguirnos en el canal de YouTube donde pronto trataré de mostrar la configuración paso a paso de este tipo de Always On.

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

Publicado por Roberto Carrancio en Alta Disponibilidad, SQL Server, 0 comentarios

¿Qué pasa con la inicialización instantánea de ficheros al habilitar TDE?

La inicialización instantánea de ficheros (Instant File Initialization, IFI) es una funcionalidad crucial en SQL Server que reduce significativamente los tiempos de ciertas operaciones, como la creación de bases de datos, la restauración de backups y el crecimiento de archivos. Sin embargo, al activar el cifrado transparente de datos (Transparent Data Encryption, TDE), los beneficios de IFI se pierden debido a los requisitos inherentes de seguridad que impone TDE. En este artículo analizaremos con mayor profundidad cómo interactúan ambas tecnologías, los motivos detrás de esta interacción y las estrategias para gestionar su impacto en entornos de producción.

Entendiendo la inicialización instantánea de ficheros

Cuando SQL Server asigna espacio en disco para bases de datos o archivos de log, el sistema operativo, por defecto, rellena este espacio con ceros. Este proceso garantiza que no queden accesibles datos residuales en los bloques de disco, lo que protege la privacidad de la información eliminada. Sin embargo, este paso puede ralentizar considerablemente ciertas operaciones en SQL Server. La inicialización instantánea de ficheros (IFI) permite omitir este relleno, lo que acelera estas operaciones críticas:

Creación de bases de datos grandes

Al crear una base de datos nueva, SQL Server asigna espacio en disco para los archivos de datos y de log. Si IFI no está habilitado, este espacio debe ser rellenado con ceros antes de que la base de datos esté lista para usarse. En bases de datos grandes, esto puede significar tiempos de espera considerables. Con IFI, el espacio se asigna sin esta inicialización, haciendo que el proceso sea prácticamente inmediato.

Restauración de backups grandes

Restaurar una base de datos desde un backup implica no sólo copiar los datos al sistema de archivos, sino también asignar espacio en disco para los archivos restaurados. Sin IFI, SQL Server debe rellenar con ceros el espacio asignado antes de restaurar los datos, lo que prolonga el tiempo necesario para completar la operación. Esto puede ser crítico en escenarios de recuperación ante desastres, donde cada minuto cuenta.

Crecimiento automático de archivos

SQL Server permite configurar bases de datos y archivos de log con crecimientos automáticos para evitar errores de espacio insuficiente. Cuando un archivo necesita crecer, SQL Server asigna más espacio en disco. Si IFI no está habilitado, este espacio adicional debe inicializarse con ceros antes de que el archivo pueda seguir utilizándose, causando retrasos en operaciones que requieren escribir inmediatamente en el archivo.

 

La inicialización instantánea de ficheros está diseñada para mitigar estos cuellos de botella. Para habilitar esta funcionalidad, la cuenta de servicio de SQL Server debe tener asignado el privilegio «Perform volume maintenance tasks» en el sistema operativo. Esto permite que SQL Server omita el paso de rellenar el espacio asignado con ceros, mejorando drásticamente el rendimiento de las operaciones mencionadas. Puedes encontrar más información sobre cómo configurar este privilegio y sus beneficios en nuestro artículo dedicado aquí.

¿Qué es TDE y por qué afecta a la inicialización instantánea?

Transparent Data Encryption (TDE) es una tecnología diseñada para cifrar datos en reposo en SQL Server y proteger la información en caso de accesos no autorizados a los archivos físicos de la base de datos. Cuando TDE está habilitado, todos los datos almacenados en los archivos de la base de datos (incluidos los logs de transacciones) se cifran mediante una clave de cifrado jerárquica. Puedes encontrar más detalles en nuestro artículo sobre cifrado en SQL Server y en este video sobre TDE.

El problema al activar TDE es que SQL Server no puede aprovechar la inicialización instantánea de ficheros. En lugar de simplemente asignar espacio en disco, debe escribir datos cifrados en ese espacio para evitar que datos residuales sin cifrar queden expuestos en los bloques del sistema de archivos. Este proceso introduce una sobrecarga significativa, especialmente en operaciones como:

  • Crecimiento de archivos: Tanto los archivos de datos (.mdf, .ndf) como los archivos de log (.ldf) deben inicializarse completamente al ampliarse.
  • Restauración de bases de datos: Requiere cifrar todo el espacio asignado antes de completar el proceso.
  • Creación de bases de datos: Similar a la restauración, el tiempo de inicialización aumenta notablemente.

El impacto de TDE en el rendimiento y cómo gestionarlo

El impacto de la pérdida de IFI en bases de datos con TDE puede ser considerable, especialmente en sistemas con alta actividad transaccional o que manejan bases de datos de gran tamaño. Sin embargo, no todo está perdido. A continuación os dejo una lista de acciones que podemos hacer para mitigar estos daños.

Planificación proactiva del crecimiento de archivos

Configurar tamaños iniciales de archivos y establecer crecimientos manuales y controlados puede reducir la frecuencia de eventos de crecimiento automático. Por ejemplo, asignar bloques grandes de espacio en lugar de pequeños incrementos minimiza la necesidad de inicializaciones frecuentes.

Optimización del almacenamiento

El uso de discos SSD y configuraciones RAID de alto rendimiento puede acelerar las operaciones de escritura asociadas con la inicialización. Además, separar los discos para archivos de datos y de log permite distribuir la carga.

Compresión de backups

La compresión de backups no es que reduzca el tamaño del archivo a restaurar por lo que el tiempo necesario para inicializar el espacio cifrado será el mismo. Sin embargo, esta técnica nos permitirá ganar tiempo a la hora de mover o restaurar estos archivos desde la red. Puedes consultar este video donde comparamos tiempos de copias y restauraciones con y sin comprimir.

Segmentación del uso de TDE

No todas las bases de datos requieren un nivel extremo de seguridad. Analizar qué bases necesitan realmente TDE y aplicar la encriptación sólo en aquellas esenciales puede equilibrar el rendimiento y la seguridad.

Supervisión activa

La monitorización constante del rendimiento puede ayudar a identificar cuellos de botella relacionados con la inicialización de archivos. Herramientas como Extended Events o el Query Store pueden proporcionar visibilidad sobre las operaciones afectadas.

Consideraciones avanzadas con TDE: recuperación y restauración

Uno de los mayores retos al combinar TDE con la pérdida de la inicialización instantánea de ficheros nos lo vamos a encontrar en los tiempos de restauración. Este aspecto es crítico en entornos de alta disponibilidad y recuperación ante desastres. Los administradores de bases de datos debemos tener en cuenta la necesidad de probar y ajustar los procesos de recuperación regularmente para entender el impacto real en tiempos de inactividad.Con esto en mente podremos configurar estrategias de recuperación que incluyan bases de datos en modo Standby o soluciones como Always On Availability Groups para minimizar el tiempo necesario en caso de fallos.

Conclusión: seguridad de TDE vs rendimiento de IFI

La interacción entre la inicialización instantánea de ficheros y el cifrado transparente de datos pone en evidencia el constante balance entre seguridad y rendimiento que enfrentamos como administradores de bases de datos. Aunque IFI es una herramienta valiosa para optimizar operaciones críticas, su incompatibilidad con TDE subraya la importancia de priorizar la seguridad de los datos en entornos sensibles.

Con un enfoque proactivo y la implementación de mejores prácticas, podemos minimizar el impacto de esta limitación y garantizar que nuestras bases de datos sean tanto seguras como eficientes.

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

 

Publicado por Roberto Carrancio en Rendimiento, SQL Server, 0 comentarios

Los peligros del permiso SHOWPLAN

Cuando administramos bases de datos en SQL Server, no debemos perder el foco en asegurar la confidencialidad, integridad y disponibilidad de los datos. Sin embargo, a veces, centrados en el rendimiento, subestimamos cómo ciertos permisos pueden abrir brechas de seguridad inesperadas. Uno de estos permisos es SHOWPLAN. ¿Alguna vez le has dado permisos de SHOWPLAN en producción a un desarrollador? Puede parecer inofensivo y además es una herramienta poderosa y útil para que los desarrolladores puedan optimizar sus consultas, pero no es tan sencillo. ¿Sabías que puede convertirse en un riesgo significativo si se concede de manera inapropiada? A continuación, te cuento en profundidad qué implica este permiso, sus ventajas legítimas y los riesgos que puede acarrear cuando se utiliza fuera de contexto.

¿Qué es el permiso SHOWPLAN?

El permiso SHOWPLAN en SQL Server permite a los usuarios generar y visualizar los planes de ejecución de las consultas. Esto incluye detalles sobre cómo el motor de base de datos planea ejecutar una consulta SQL, mostrando operaciones como búsquedas en índices, uniones, escaneos de tablas, y predicados de filtro.

Existen dos variantes principales de este permiso, SHOWPLAN_XML y SHOWPLAN_TEXT, que permiten generar una representación del plan de ejecución en formato XML o texto, respectivamente. Además, SHOWPLAN_ALL muestra información completa sobre el plan de ejecución.

Cuando se activa este permiso, SQL Server no ejecuta realmente la consulta, sino que devuelve un «plan estimado», describiendo cómo se procesaría la consulta en términos de operaciones lógicas y físicas.

Ventajas del permiso SHOWPLAN

El permiso SHOWPLAN tiene aplicaciones legítimas y valiosas en el desarrollo y mantenimiento de bases de datos. Entre sus principales beneficios, podríamos destacar los siguientes:

Identificación de problemas de rendimiento

 La principal utilidad del permiso SHOWPLAN es ayudar a identificar cuellos de botella en el rendimiento de las consultas. Tanto los administradores de bases de datos (DBAs) y desarrolladores podemos usar esta información para optimizar consultas, ajustar índices o rediseñar tablas. Por ejemplo, un plan de ejecución puede revelar que una consulta está realizando un «escaneo completo de tabla» (Table Scan) en lugar de usar un índice, lo que indica la necesidad de crear un índice o ajustar el predicado.

Análisis predictivo sin ejecutar consultas 

Con SHOWPLAN, es posible analizar cómo SQL Server ejecutaría una consulta sin necesidad de ejecutarla realmente. Esto es crucial cuando se trabaja con consultas que afectan grandes volúmenes de datos, ya que permite evaluar su impacto sin riesgo de sobrecargar el sistema.

Comparación de estrategias de consulta 

Los desarrolladores pueden usar SHOWPLAN para comparar alternativas de diseño de consultas. Por ejemplo, al evaluar si una subconsulta correlacionada es más eficiente que una JOIN, los planes de ejecución ayudan a elegir la mejor estrategia.

Herramienta educativa y formativa 

En entornos de desarrollo, SHOWPLAN también se usa para enseñar a nuevos DBAs y desarrolladores cómo optimizar consultas y comprender el comportamiento interno de SQL Server. Es una herramienta ideal para profundizar en cómo el optimizador toma decisiones.

Riesgos asociados al permiso SHOWPLAN

Aunque las ventajas de SHOWPLAN son innegables en manos de DBAs y desarrolladores, los riesgos emergen cuando este permiso se concede a usuarios fuera de estos roles o sin las medidas de seguridad adecuadas.

Exposición de datos sensibles 

Una característica poco conocida de SHOWPLAN es que los planes de ejecución pueden revelar los valores exactos de las variables o parámetros utilizados en las consultas. Aunque un usuario no tenga acceso directo a las tablas implicadas, podría deducir información confidencial a través del análisis del plan.

Por ejemplo si ves esta consulta en ejecución:

El plan de ejecución en XML mostrará que @Numero contiene un valor como 1234-5678-9012-3456, exponiendo información sensible. 

Mapeo de la estructura de la base de datos

Los planes de ejecución muestran detalles como nombres de índices, columnas y relaciones entre tablas. Un usuario malintencionado podría utilizar esta información para mapear la estructura de la base de datos y diseñar ataques dirigidos, como inyecciones SQL más efectivas o extracción de datos. 

Imagina que alguien, gracias a técnicas de SQLi es capaz de vulnerar la seguridad de tu app y llegar a la base de datos. Si el usuario de la aplicación tiene más permisos de los estrictamente necesarios el daño puede ser gravísimo.

Ingeniería inversa de estadísticas 

Los planes de ejecución contienen estadísticas sobre cardinalidad y distribución de datos, lo que permite deducir patrones sensibles, como la cantidad de registros que cumplen ciertas condiciones. Esto podría facilitar ataques de análisis estadístico. Sumale a esto los anteriores peligros y tendrás el cóctel perfecto para una fuga inesperada de datos.

Uso en ataques de denegación de servicio (DoS)

Por último, pero no menos importante, un usuario malintencionado con acceso a SHOWPLAN podría diseñar consultas costosas que generen planes de ejecución extremadamente complejos, agotando recursos del servidor.

Mejores prácticas para mitigar los riesgos de SHOWPLAN

Para evitar que el permiso SHOWPLAN se convierta en un vector de ataque, es esencial adoptar un enfoque de seguridad robusto que contemple varias estrategias complementarias. En primer lugar, es imprescindible seguir el principio de menor privilegio, limitando el uso de este permiso exclusivamente a administradores de bases de datos (DBAs) y algunos desarrolladores, y exclusivamente en entornos de desarrollo o pruebas. En producción, el acceso debe ser excepcional y estrictamente controlado.

Cuando se trabaja con bases de datos reales en entornos de prueba, la anonimización o el enmascaramiento de datos son medidas clave para evitar la exposición accidental de información sensible. Esta práctica protege los datos al tiempo que permite un análisis seguro del rendimiento de las consultas.

Además, las auditorías regulares resultan fundamentales para identificar usuarios que dispongan de permisos sensibles como SHOWPLAN. Herramientas nativas como Extended Events en SQL Server pueden facilitar el rastreo y análisis del uso de este permiso, asegurando un monitoreo constante de posibles accesos indebidos.

Por último, la formación continua de los equipos de desarrollo y administración es un pilar esencial. Educar a los responsables sobre los riesgos asociados al uso indebido de permisos sensibles y las mejores prácticas para gestionarlos garantiza que las concesiones innecesarias puedan evitarse de manera efectiva, fortaleciendo así la postura de seguridad general del entorno.

Conclusión

El permiso SHOWPLAN es una gran herramienta para la optimización de consultas y el análisis del rendimiento en SQL Server, pero su mal uso puede comprometer la seguridad de los datos. Concederlo sin restricciones puede exponer datos sensibles, facilitar ataques y comprometer la integridad del sistema.

Para evitar estos riesgos, es esencial adoptar un enfoque de seguridad proactiva, restringiendo su uso a roles específicos, monitoreando su aplicación y utilizando alternativas seguras cuando sea posible. De esta manera, podemos aprovechar las ventajas de SHOWPLAN sin comprometer la seguridad de nuestras bases de datos. Como siempre, en SQL Server, un enfoque basado en “confianza cero» (Zero Trust) es la mejor política.

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

Publicado por Roberto Carrancio en Cloud, Rendimiento, SQL Server, 0 comentarios