Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Réflexions sur la sécurité de SQL Server

Le DBA est le gardien des données, et il y a deux aspects à être un gardien. Le premier est l'intégrité. Cela inclut des tâches telles que la vérification de la cohérence de la base de données, la création de sauvegardes et, en cas de problème, la mise en place d'un plan de récupération de base de données complet et bien conçu.

Le deuxième aspect est la sécurité. Il suggère de s'assurer que seuls les utilisateurs autorisés ont accès aux données, et uniquement aux données dont ils ont besoin.

Vous pouvez trouver de nombreuses ressources dédiées à la sécurité sur le Web. Cependant, je pense que certaines choses importantes manquent d'attention appropriée. Dans cet article, je voudrais me concentrer sur ces options et démontrer pourquoi il est important d'en être conscient et de les gérer correctement.

Une mission pour compromettre un serveur SQL

Organisons un jeu de rôle dans lequel vous êtes un agent secret et votre mission, si vous l'acceptez, est de voler des données très importantes de la TargetDB base de données hébergée par un serveur SQL. Vous devez récupérer ces données et les supprimer.

Il est possible d'obtenir une connexion pour vous, mais chaque connexion sur le serveur a des autorisations REFUSÉES explicites sur la base de données et les données cibles. Les seules informations que notre agent peut vous fournir sont celles générées pour vérification par le protocole de sécurité lors de la création de votre login.

Informations de base de données du serveur cible.

Autorisations du serveur :

Autorisations de base de données :

Comme tout bon agent, faisons nos devoirs et vérifions à quoi vous avez affaire.

Vous ne pouvez pas simplement vous connecter et vous connecter à TargetDB , puisque chaque autorisation est refusée pour votre connexion et son utilisateur mappé explicitement. Vous devez accéder à partir d'une autre base de données.

Une porte verrouillée

Les actions inter-bases de données ne sont pas des choses faciles à faire. Considérez-le comme une porte fermée avec deux serrures dessus. Nous ne nous concentrerons pas sur les détails techniques ici, mais vous pouvez vous référer à l'article Extension de l'emprunt d'identité de base de données en utilisant EXECUTE AS MSDN (je vous le recommande vivement).

Le premier verrou est Faire confiance à l'authentificateur , et le second est Faire confiance à la base de données .

Commençons par la première serrure. Faire confiance à l'authentificateur signifie que pour accéder à une autre base de données B, le propriétaire de la base de données A doit recevoir (explicitement ou implicitement) le AUTHENTICATE autorisation dans la base de données B.

Attendez une minute! L'authentificateur au niveau de la base de données est le propriétaire de la base de données elle-même (ne le confondez pas avec le db_owner rôle de base de données !).

Vérifiez les propriétaires de la base de données :

Même s'ils suivent une assez bonne pratique en utilisant un compte par serveur, qui n'est pas SA , de cette façon, ils ont gentiment ouvert la première serrure pour vous.

Concentrons-nous sur le deuxième verrou.

D'une manière ou d'une autre, vous devez avoir une base de données créée sur le serveur avec le TRUSTWORTHY propriété ON . La meilleure pratique ici consiste à définir la propriété de base de données TRUSTWORTHY sur OFF .

C'est le moment où il faut se dire :et si vous aviez déjà une telle base de données ?

Il s'agit de la base de données MSDB.

La deuxième serrure est terminée. Vous n'avez même pas eu besoin de casser les serrures.

L'importance du rôle db_owner

En ce moment, vous devez faire face à un défi. D'une manière ou d'une autre, vous devez accéder à la base de données MSDB avec le db_owner rôle de base de données, car il dispose d'une autorisation implicite et d'emprunt d'identité.

Étant donné que MSDB n'est généralement pas au centre des préoccupations des administrateurs de bases de données, cette mission n'est plus impossible. Voyons ce que vous pouvez faire simplement parce que vous avez un utilisateur avec le db_owner rôle de base de données dans la base de données MSDB :

Essayez de vous connecter à TargetDB :

Il s'agit d'une erreur attendue. Rappelez-vous le protocole de sécurité appliqué sur le login fourni. Commençons.

Essayez de vous connecter à TargetDB et pour sélectionner les données cibles :

Ça marche! Modifions-le et après cela, vérifions l'action.

C'est tout.

Mission accomplie.

Comme vous l'avez vu, je me suis concentré sur une combinaison particulière de configuration de base de données de sécurité. Ceux-ci étaient le propriétaire de la base de données et le TRUSTWORTHY option de base de données en accordant une attention particulière à MSDB. Le scénario présenté n'en était qu'un dans lequel des données sensibles peuvent être compromises de la même manière. Passons maintenant en revue un autre scénario possible.

Propriétaire de la base de données + FIABLE

Vérifions les détails de fond en commençant par le problème bien connu :la propriété de la base de données. Quelles informations de connexion le propriétaire de votre/vos base(s) de données doit-il utiliser ? Beaucoup de gens disent que SA est un choix approprié.

J'ai fait une recherche rapide sur Google et j'ai trouvé des réponses comme celles-ci :

"Je ne me souviens pas que cela ait jamais été une préoccupation pour moi. À part avoir l'air ennuyeux dans les rapports ou ne pas pouvoir supprimer l'utilisateur s'il possède une base de données, mais je ne pense pas que cela affecte les opérations du serveur. Vous pouvez simplement choisir sa pour plus de cohérence."

Ou

"Je ne pense pas que posséder une base de données par SA ou tout autre utilisateur devrait être une préoccupation. Ce qui compte, c'est qui fait « quoi » dans votre base de données. C'est donc une bonne idée de créer des utilisateurs avec des privilèges valides. Pour plus de simplicité, vous pouvez spécifier le propriétaire en tant que SA."

La situation actuelle est que utiliser le compte SA en tant que propriétaire de base de données est la PIRE pratique . Personnellement, je pense que cela devrait être mis en évidence sur chaque blog et dans chaque documentation liée à ce sujet.

Si nous créons des utilisateurs avec uniquement des privilèges valides, cela suffirait, mais malheureusement, ce n'est pas ainsi que les choses fonctionnent habituellement. Vous devez être préparé aux « pires scénarios possibles ». Pensez simplement à ce que nous pourrions faire dans nos exemples précédents si le propriétaire de la base de données par défaut était SA !

Continuons avec la deuxième option, le TRUSTWORTHY possibilité de base de données. La situation est un peu meilleure mais il y a toujours un problème commun. Comme on le considère généralement, la meilleure pratique ici consiste à Définir la propriété de base de données "digne de confiance" sur Off . Nous venons de voir pourquoi cette option est mauvaise .

Mais ce n'est pas tout. Si vous essayez de trouver des scripts pour vérifier cette propriété, vous trouverez probablement un script similaire à celui-ci :

SELECT name FROM sys.databases WHERE is_trustworthy_on = 1 AND name != 'msdb'

Le sp_Blitz Le script qui vérifie la santé de SQL Server vérifie également les paramètres par défaut des bases de données (y compris TRUSTWORTHY comme valeur par défaut de 0) et signale chaque base de données qui a des paramètres non par défaut. Cependant, le script ignore les bases de données système.

En outre, il existe un article MS KB, qui se concentre sur ce sujet. Reportez-vous aux instructions d'utilisation des paramètres de base de données TRUSTWORTHY dans SQL Server :

Il y a un exemple de code dans l'article, qui répertorie les bases de données dont le bit TRUSTWORTHY est activé et dont les propriétaires de base de données appartiennent au rôle de serveur sysadmin :

SELECT SUSER_SNAME(owner_sid) AS DBOWNER, d.name AS DATABASENAME
FROM sys.server_principals r
INNER JOIN sys.server_role_members m ON r.principal_id = m.role_principal_id
INNER JOIN sys.server_principals p ON
p.principal_id = m.member_principal_id
inner join sys.databases d on suser_sname(d.owner_sid) = p.name
WHERE is_trustworthy_on = 1 AND d.name NOT IN ('MSDB') and r.type = 'R' and r.name = N'sysadmin'

Qu'y a-t-il de commun dans ces scripts ? Chaque script exclut la MSDB, mais comme le note l'article de MS KB, vous venez de le voir dans notre "mission" :

Remarque :Par défaut, le paramètre TRUSTWORTHY est défini sur ON pour la base de données MSDB. La modification de ce paramètre à partir de sa valeur par défaut peut entraîner un comportement inattendu des composants SQL Server qui utilisent la base de données MSDB.

Je tiens à souligner que l'objectif principal de cette section n'est ni l'option de base de données TRUSTWORTHY ni la propriété du propriétaire de la base de données elle-même, mais la combinaison de ces deux options. Je me suis principalement concentré sur MSDB car le paramètre TRUSTWORTHY est défini sur ON pour la base de données MSDB par défaut.

Conclusion

C'est tout pour le moment. Nous avons parcouru et vérifié les scénarios pratiques liés à la sécurité de SQL Server. Nous avons également examiné des options de base de données aussi importantes que le propriétaire de la base de données et le paramètre de base de données TRUSTWORTHY.

Je voulais juste mettre en lumière ces options depuis - car elles sont essentielles, surtout lorsque nous en parlons en combinaison.