Sécurisation des accès aux bases de données SQL Server

SQLPro

Certains chefs de projet oublient d'intégrer au développement la sécurité des accès aux bases de données exploitées par les applicatifs. Le but de ce document est d'étudier les moyens de mettre en place cette sécurité « a posteriori ».

- Titre : Sécurisation des accès aux bases de données SQL Server

- Auteur : SQLPro

- Parution : 20 avril 2004

- Public visé :

- Licence : Copyright ® 2004 Frédéric Brouard. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Constat

- II. Le remède

- II-A. Détection des failles

- II-A-1. Accès serveur par compte par défaut (« sa »)

- II-A-2. Comptes d'accès serveur non sécurisés

- II-A-3. Rôles et utilisateurs de la base non sécurisés

- II-B. Création de mots de passe

- II-C. Sécurisation de l'accès au serveur

- II-D. Stratégie SQL Server de gestion de la sécurité

- II-E. La connexion

- III. Création de la sécurité

- III-A. Protection du compte « sa »

- III-B. Ajout d'utilisateurs et de connexions

- IV. La problématique de mise en œuvre

- IV-A. Faille dans le système

- IV-B. Mise en place à travers les applications clientes

I - Constat

La plupart du temps, l'accès au serveur se fait par le compte d'administration système (SA) sans aucun mot de passe.

Aucun utilisateur ni rôle n'ayant été créé pour l'exploitation des données, c'est donc le propriétaire des bases par défaut (dbo) qui exerce ses droits. Ceux-ci étant illimités il est possible pour les utilisateurs finals de modifier supprimer ou insérer dans toutes les bases y compris les bases système, les schémas, les données comme le code (procédures stockées et triggers notamment).

Bien évidemment, cet état de fait laisse la porte grande ouverte aux attaques de serveurs SGBD, SQL Server notamment, en particulier lorsque le réseau du client accède à Internet.

Sur la sécurité en général dans SQL Server, voir le site :
http://www.sqlsecurity.com/

II - Le remède

Le remède consiste à établir :

- un accès sécurisé au serveur ;

- plusieurs utilisateurs dotés de privilèges différents pour l'exploitation des données et des procédures.

II-A - Détection des failles

Voici les manières les plus simples pour détecter les failles de sécurité du serveur et de la base de données cible.

II-A-1 - Accès serveur par compte par défaut (« sa »)

Lors de l'accès au serveur, par exemple en appelant l'analyseur de requête depuis le menu Window, la boîte de dialogue suivante apparaît :

La faille de sécurité à ce niveau est l'autorisation d'accès avec un mot de passe vide.

NOTA : si ce n'est la boîte de dialogue de SQL Server, le mécanisme est le même dans une application écrite en langage hôte.

II-A-2 - Comptes d'accès serveur non sécurisés

Une fois connecté au serveur, exécuter la requête suivante sur la base master (à défaut, exécutez préalablement USE MASTER GO ) :

SELECT NAME, PASSWORD
FROM SYSLOGINS
WHERE (PASSWORD IS NULL AND NAME IS NOT NULL)
OR (PASSWORD = '' AND NAME IS NOT NULL)

La faille de sécurité à ce niveau est la présence de lignes dans la table. Ces lignes indiquent quels comptes d'accès au serveur sont dépourvus de mot de passe ou bien dotés d'un mot de passe constitué par une chaîne vide.

II-A-3 - Rôles et utilisateurs de la base non sécurisés

Toujours dans la connexion ouverte, exécuter la requête suivante sur la base master (à défaut, exécutez préalablement USE MASTER GO ) :

select *
from sysusers
where (password is null) or (password = CAST('' as VARBINARY(128)))

La faille de sécurité à ce niveau est la présence de lignes dans la table. Ces lignes indiquent quels utilisateurs des différentes bases sont dépourvus de mot de passe ou bien dotés d'un mot de passe constitué par une chaîne vide.

II-B - Création de mots de passe

Un bon mot de passe est un mot de passe :

- qui comporte un minimum de 6 à 8 caractères ;

- ne comporte pas de caractères au-delà des 128 premiers du jeu de base hormis les caractères non imprimables ;

- comporte un mélange de minuscules, majuscules, de lettres et de chiffres, et au moins un signe de ponctuation ;

- est changé fréquemment (plusieurs fois par an) ;

- est généré par un générateur automatique de mots de passe utilisant un générateur aléatoire de caractères.

Il existe des sites de pirates informatiques recensant les quelques centaines de mots de passe les plus utilisés et certains programmes sont disponibles sur Internet pour utiliser une telle liste afin d'accéder à certains logiciels.

On devra donc veiller à mettre des mots de passe suffisamment sûrs.

Liste des mots de passe des constructeurs :
http://www.astalavista.com/library/auditing/password/lists/defaultpasswords.shtml
http://www.phenoelit.de/dpl/dpl.html

II-C - Sécurisation de l'accès au serveur

L'accès au serveur doit se faire par un compte autre que « sa » et avec un mot de passe sur le compte. Le compte « sa » doit être réservé aux opérations d'administration et maintenance lourdes telles que la sauvegarde et la restauration de données.

NOTA : les mots de passe ne sont pas visibles par requêtes même lorsque l'on est administrateur de la base de données.

Exemple :

SELECT NAME, PASSWORD
FROM SYSLOGINS

Donne :

NAME                           PASSWORD
------------------------------ -------------------------------
sa                             ????????

Tant et si bien que la perte de mots de passe est une opération non récupérable sauf depuis une sauvegarde.

ATTENTION : si le paramétrage par défaut de SQL Server est en casse insensible (option à déconseiller), alors le mot de passe pourra être saisi indifféremment en majuscules ou minuscules.

NOTA : la sécurité d'accès effectuée au niveau de la base est la plus sûre qui puisse se faire. Gérer la sécurité uniquement à travers une application est une utopie puisque de nombreux outils peuvent accéder au middleware ODBC, notamment l'ensemble des outils Microsoft Office.

II-D - Stratégie SQL Server de gestion de la sécurité

SQL Server propose deux stratégies de gestion des droits. L'une est intégrée à l'OS Windows NT et se repose sur les comptes d'utilisateurs système. L'autre est basée sur une technique plus proche de ce que la norme SQL propose, c'est-à-dire une grande indépendance entre les utilisateurs du système et les utilisateurs des bases de données.

ATTENTION : la stratégie de droits reposant sur les droits des utilisateurs système est à déconseiller totalement : elle n'est absolument pas portable (donc impossible pour un éditeur ou un prestataire à mettre en œuvre chez son client) et a causé de multiples problèmes dans les versions précédentes. De fait, Microsoft a réintroduit la seconde solution qui était celle de Sybase au départ lorsque Microsoft à racheté le produit SQL Server à cet éditeur.

Alors que la norme SQL 2 ne propose pas plus que la définition d'utilisateurs et l'octroi (GRANT, REVOKE) de privilèges, MS SQL serveur y rajoute l'octroi DENY et propose la notion de rôles de base de données et de serveur, très proche de la norme SQL3 (pour plus d'informations concernant la gestion des privilèges SQL, « lire La Gestion des Privilèges ».

Un « rôle » est en fait un groupe d'utilisateurs possédant des droits communs.

Un utilisateur est un accès à la base et doit appartenir au moins à un rôle.

ATTENTION : une mauvaise manipulation de ces rôles et utilisateurs peut faire perdre définitivement tout accès à certaines bases, voire au serveur. L'important et de ne modifier en aucun cas, ni le compte ni les droits attribués au compte « sa ».

SQL Server propose des rôles préétablis, présents dans toutes les bases de données. Il s'agit des rôles suivants :

rôle

utilisation

public

par défaut

db_owner

créateur par défaut des objets de la base, il possède toutes les autorisations sur la base de données.

db_accessadmin

gère les accès : ajoute ou supprime des ID utilisateur.

db_securituadmin

gère les droits : accès, propriétés d'objet, rôles et membres des rôles.

db_ddladmin

gestion des droits au niveau du sous-ensemble DDl du SQL : lance l'instruction ALL DDL mais pas les instructions GRANT, REVOKE ou DENY.

db_backupoperator

opérateur de sauvegarde (mais pas de restauration !). Lance les instructions DBCC, CHECKPOINT et BACKUP.

db_datareader

droit de consultation des données de la base (lecture uniquement). Sélectionne toutes les données de toutes les tables utilisateur dans la base de données.

db_datawriter

droit en lecture, écriture des données de la base. Modifie les données de toutes les tables utilisateur dans la base de données.

db_denydatareader

révocation des droits en lecture sur tous les objets de la base.

db_denydatawriter

révocation des droits en écriture sur tous les objets de la base.

En principe il n'y a pas lieu de créer de nouveaux rôles, mais simplement de créer des utilisateurs et d'y affecter un ou plusieurs rôles parmi ceux préétablis.

Les rôles db_deny… permettent de placer des utilisateurs dans ces rôles afin d'interdire immédiatement certains droits.

ATTENTION : une confusion classique consiste à considérer l'utilisateur SQL comme une personne physique, un utilisateur de PC par exemple. C'est un non-sens absolu. L'utilisateur SQL, n'est autre en général qu'une application cliente…

II-E - La connexion

En définitive, ce que voit l'utilisateur de l'application, comme ce que fait l'utilisateur d'un SGBDR MS SQL Server, c'est d'activer sa connexion. Il faut donc automatiser la gestion des droits par le biais de la connexion.

Le nom d'une connexion ne peut :

- contenir de barres obliques inversées (\) ;

- correspondre à un nom réservé, par exemple « sa » ou « public » ou bien déjà exister ;

- avoir la valeur NULL ou être une chaîne vide ('').

NOTA : l'élément clef de la gestion de la sécurité au sein de SQL Server est la connexion : la connexion définit la base par défaut et l'utilisateur par défaut doté de ses privilèges.

III - Création de la sécurité

La sécurité doit être mise en place en deux phases : protection du compte « sa » puis création de nouvelles connexions dotées de droits.

III-A - Protection du compte « sa »

La première phase consiste à doter le compte « sa » d'un mot de passe difficile à trouver.
Une fois connecté au compte « sa » (sans mot de passe), il faut ajouter le mot de passe que l'on veut donner à ce compte à l'aide de la procédure stockée sp_password, dont la syntaxe est :

sp_password 'mot_de_passe_actuel', 'nouveau_mot_de_passe', 'connexion'

Exemple :

Use master
sp_password NULL, 'd1A*cv4:', 'sa'

Donne le mot de passe « d1A*cv4: » au compte « sa ».

Les utilisateurs déjà connectés en « sa » continuent de voir la base de données, tandis que les nouveaux accédants doivent impérativement donner le nouveau mot de passe.

III-B - Ajout d'utilisateurs et de connexions

L'ajout d'un utilisateur affecté à des rôles prédéterminés se fait en deux temps :

- création de la connexion ;

- ajout d'un utilisateur et de son rôle.

Les procédures stockées à utiliser sont les suivantes :

sp_addlogin 'connexion', 'mot_de_passe', 'base_cible'

sp_adduser 'connexion', 'utilisateur', 'rôle'

NOTA : il est nécessaire d'utiliser la base de données cible.

Exemple : création d'un utilisateur nommé usr_lecteur dont la connexion est log_lecteur, le mot de passé kw7E.6J et possédant le rôle de lecteur uniquement :

use maBase
go

exec sp_addlogin 'log_lecteur', 'kw7E.6J', 'maBase'
go

sp_adduser 'log_lecteur', 'usr_lecteur', 'db_datareader'
go

Pour tester la validité de cette sécurité, il suffit de se connecter au serveur avec le compte d'utilisateur log_lecteur et le mot de passe kw7E.6J. Dès lors toute tentative d'insertion de mise à jour ou de suppression se soldera par une inaction accompagnée d'un message d'erreur tel que :

Serveur: Msg 229, Niveau 14, État 5, Ligne 1
Autorisation DELETE refusée sur l'objet 'maTable', base de données 'maBase', propriétaire 'dbo'.

De même un changement de base cible provoquera l'apparition d'un message d'erreur, comme celui-ci :

IV - La problématique de mise en œuvre

Différents problèmes vont rentrer en jeu à la fois lors de la mise en œuvre sur le plan pratique de la sécurité, mais aussi tout au long de la vie du serveur et des bases de données qu'il contient, tout particulièrement en ce qui concerne l'évolution de la structure de la base et la maintenance du serveur.

IV-A - Faille dans le système

Une importante faille existe sur SQL Server. En effet lors de la sauvegarde d'une base de données les rôles et les utilisateurs ne sont pas stockés. Ce qui fait qu'en cas de restauration d'une base, celle-ci est déprotégée !

À lire sur le sujet : http://www.swynk.com/friends/boyle/fixingbrokenlogins.asp.

Il convient donc de remettre en place systématiquement ces éléments de sécurité.
C'est aussi pourquoi il faut se poser la question de la responsabilité de la détention du compte « sa » et de sa communication aux utilisateurs, même les plus avertis.
Le cas de l'éditeur de progiciels est particulier. La pratique consiste à sécuriser la base suffisamment fortement pour que, au quotidien :

- le client ait tous les droits de lecture sur toutes les informations stockées dans la base ;

- le client n'ait aucun droit de modification des données de la base, sauf à passer par l'application ;

- le client puisse effectuer quotidiennement les sauvegardes ;

- en cas de restauration, une procédure particulière permette cette reprise de données, même en cas de défaillance de l'éditeur, mais que cette procédure lève la responsabilité de l'éditeur tant que ce dernier n'a pas été informé et protège à nouveau la base.

Par exemple cette procédure peut consister d'une part en une enveloppe cachetée comprenant le mot de passe d'accès au compte « sa » et d'autre part l'automatisation dans l'application de la reprotection automatique en cas de défaillance des mots de passe habituels.

L'interdiction de modification des données, peut se faire par un trigger contrôlant un code de cohérence dont l'algorithme est tenu secret. Pour ce faire le mode de cryptage est requis pour la création de ces triggers.

IV-B - Mise en place à travers les applications clientes

La mise en place d'une sécurité a posteriori comporte quelques écueils qu'il convient d'éviter notamment lorsque l'application est distribuée et qu'une télé action systématique sur tous les postes de travail est difficilement envisageable.
Dans ce cas, il convient de prévoir l'autogestion systématique de la mise en place de la sécurité.

L'organigramme fonctionnel peut se résumer dans ce cas aux étapes suivantes :

1. L'applicatif tente de se connecter avec un compte en lecture écriture seulement ;

2. Il y parvient => FIN :

3. Il n'y parvient pas => l'applicatif se connecte avec le compte administrateur ancien non protégé, puis applique le script de protection.

L'inconvénient est que ce mode peut prendre un temps assez important notamment si le « time out » de connexion a une durée assez longue.

Le mot de passe devra être stocké dans l'applicatif, mais de façon non compréhensible notamment si l'outil de développement produit du code interprété (cas de Windev, Visual Basic…).
Il pourra aussi être stocké de manière externe, dans un fichier de ressources par exemple (*.ini ou registre de Windows) notamment si les applicatifs sont personnalisés par poste ou par utilisateurs système.

On aura tout intérêt à crypter la chaîne de caractères contenant le mot de passe, à l'aide d'une fonction bijective, par exemple de la manière suivante :
mot de passe original : 123456789
mot de passe stocké : 192837465
en reprenant le premier puis le dernier caractère et ainsi de suite par élimination des caractères déjà repris.

Enfin, à chaque fois qu'il faudra modifier le schéma de la base, il faudra prévoir dans le code applicatif l'usage du compte « sa » et donc son mot de passe. Cela laisse entendre que l'application doit être découpée en deux parties : un exécutable à destination de l'utilisateur et un autre exécutable (pouvant être lancé par le premier) à destination du serveur de base de données pour applications des modifications de structure de la base.