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

Certains chef 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".

Article lu   fois.

L'auteur

Site personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

1. 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 utilisateur finaux de modifier supprimer ou insérer dans toutes les bases y compris les bases systèmes, 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/

2. 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.

2.1. 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.

2.1.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 :

Image non disponible

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.

2.1.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 ) :

 
Sélectionnez

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 de vide.

2.1.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 ) :

 
Sélectionnez

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 de vide.

2.2. 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 minuscule, majuscule, de lettres et de chiffre, 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

2.3. 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 de 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 :

 
Sélectionnez

SELECT NAME, PASSWORD
FROM SYSLOGINS

Donne :

 
Sélectionnez

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

Tant est 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éconseillée), alors le mot de passe pourra être saisi indifféremment en majuscule ou minuscule.

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.

2.4. 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 base de données.

ATTENTION : la stratégie de droits reposant sur les droits des utilisateurs Système est a déconseillé totalement : elle n'est absolument pas portable (donc impossible pour un éditeur ou un prestataire à mettre en œuvre chez son client) et à 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'octroit (GRANT, REVOKE) de privilèges, MS SQL serveur y rajoute l'octroit 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'information concernant la gestion des privilèges SQL, "lire La Gestion des Privilèges".

Un "rôle" est en fait un groupe d'utilisateur 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ésent dans toutes les bases de données. Il s'agit des rôles suivants :

role 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 nouveau 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...

2.5. 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éfini la base par défaut et l'utilisateur par défaut dotés de ses privilèges.

3. 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és de droits.

3.1. Protection du compte "sa"

Le première phase consiste à doter le compte "sa" d'un mot de passe difficile à chercher.
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 :

 
Sélectionnez

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

Exemple :

 
Sélectionnez

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.

3.2. Ajout d'utilisateurs et de connexions

L'ajout d'un utilisateur affectés à 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 :

 
Sélectionnez

sp_addlogin 'connexion', 'mot_de_passe', 'base_cible'
 
Sélectionnez

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 :

 
Sélectionnez

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é d'un message d'erreur tel que :

 
Sélectionnez

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 :

Image non disponible

4. La problématique de mise en oeuvre

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.

4.1. 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ées. Ce qui fait qu'en cas de restauration d'une base, celle-ci est déprotégée !

A 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êmes les plus avertis.
Le cas de l'éditeur de progiciel 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.

4.2. 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'auto gestion 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ée 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ée : 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.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Livres
SQL - développement
SQL - le cours de référence sur le langage SQL
Avant d'aborder le SQL
Définitions
SGBDR fichier ou client/serveur ?
La base de données exemple (gestion d'un hôtel)
Modélisation MERISE
Mots réservés du SQL
Le SQL de A à Z
Les fondements
Le simple (?) SELECT
Les jointures, ou comment interroger plusieurs tables
Groupages, ensembles et sous-ensembles
Les sous-requêtes
Insérer, modifier, supprimer
Création des bases
Gérer les privilèges ("droits")
Toutes les fonctions de SQL
Les techniques des SGBDR
Les erreur les plus fréquentes en SQL
Les petits papiers de SQLPro
Conférence Borland 2003
L'héritage des données
Données et normes
Modélisation par méta données
Optimisez votre SGBDR et vos requêtes SQL
Le temps, sa mesure, ses calculs
QBE, le langage de ZLOOF
Des images dans ma base
La jointure manquante
Clefs auto incrémentées
L'indexation textuelle
L'art des "Soundex"
Une seule colonne, plusieurs données
La division relationnelle, mythe ou réalité ?
Gestion d'arborescence en SQL
L'avenir de SQL
Méthodes et standards
Les doublons
SQL Server
Eviter les curseurs
Un aperçu de TRANSACT SQL V 2000
SQL Server 2000 et les collations
Sécurisation des accès aux bases de données SQL Server
Des UDF pour SQL Server
SQL Server et le fichier de log...
Paradox
De vieux articles publiés entre 1995 et 1999 dans la défunte revue Point DBF

  

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.