| 5.4 Sécurité générale du serveur
 5 Administration du serveur
 Manuel de Référence MySQL 4.1 : Version Française
 
 ->Guide de sécurité
 . Protéger MySQL contre les attaques
 . Options de démarrage qui concernent la sécurité
 . Problèmes de sécurité avec LOAD DATA LOCAL
 
 
 | 
  5.4.1 Guide de sécurité 
 
Tous ceux qui utilisent MySQL avec un serveur connecté à Internet doivent 
lire cette section, pour éviter les erreurs les plus communes.
En parlant de sécurité, nous devons insister sur la nécessiter de protéger
tout le serveur, et non pas juste MySQL, contre tous les types d'attaques : 
surveillance des communications, usurpation, ré-exécution et dénis de 
service. Nous ne pouvons pas couvrir tous les aspects de tolérance aux 
fautes et de disponibilité ici. 
MySQL dispose d'un système de sécurité basé sur des listes de contrôle
d'accès ( 
Access Control Lists
 , or  
ACL
 ) pour toutes les connexions,
requêtes et opérations que l'utilisateur peut faire. Il y a aussi
le support des connexions SSL entre le client et le serveur MySQL. De nombreux
concepts présentés ici ne sont pas spécifiques à MySQL : le même
concept s'applique à de nombreuses applications.
Lorsque vous utilisez MySQL, suivez ces règles aussi souvent que possible : 
Ne donnez jamais à personne (sauf aux comptes MySQL 
root
) 
accès à la table 
user
 de la base 
mysql
!
   C'est primordial.
 
Le mot de passe chiffré est le vrai mot de passe de MySQL.
  Toute personne
qui connaît le mot de passe de la table  
user
  et qui a accès à l'hôte
associé   
peut facilement se connecter sous le nom de cet utilisateur
 .
Apprenez à fond le système de droits MySQL. Les commandes  
GRANT
  et
 
REVOKE
  sont utilisées pour contrôler les accès à MySQL. 
Ne donnez pas plus de droits que nécessaire. Ne donnez jamais de droits
à tous les serveurs hôtes.Liste de vérification :
 
Essayez la commande en ligne  
mysql -u root
 . Si vous pouvez vous connecter,
sans donner de mot de passe, vous avez un problème. Toute personne peut se connecter
au serveur comme utilisateur  
root
  avec le maximum de droits! 
Passez en revue les instructions d'installation de MySQL, en insistant sur les
passages où le mot de passe  
root
  est configuré.
 Sécurisation des comptes MySQL initiaux .
Utilisez la commande  
SHOW GRANTS
  et vérifiez qui a accès à quoi. Puis,
utilisez la commande  
REVOKE
  pour retirer les droits inutiles.
Ne stockez jamais de mot de passe en clair dans votre base de données.
Si votre serveur est compromis, le pirate aura alors la liste complète
des mots de passe, et pourra les utiliser. A la place, utilisez 
 
MD5()
 ,  
SHA1()
  ou une autre fonction de signature injective.
Ne choisissez pas vos mots de passe dans un dictionnaire. Il y a des programmes
spéciaux pour les rechercher. Même des mots de passe tels que 
`` 
xfish98
 '' est très faible. Par contre, `` 
duag98
 '' est bien mieux : 
il contient aussi le mot ``fish'' mais décalé d'une touche sur un clavier
 
QWERTY
 . Une autre méthode de génération consiste à prendre la première
lettre de chaque mot d'une phrase : ``Maupa'' est issu de ``Marie a un petit agneau.'' 
C'est facile à retenir, mais difficile à devenir pour un attaquant.
Investissez dans un coupe-feu. Cela protège de 50% de tous les types
d'attaque et vulnérabilité. Placez MySQL derrière le coupe-feu, ou dans
une zone démilitarisée ( 
DMZ
 ).Liste de vérification :
 
Essayez de scanner vos portes depuis l'Internet, avec des outils comme
 
nmap
 . MySQL utilise le port 3306 par défaut. Ce port ne doit pas
être accessible à tous les serveurs. Une autre méthode simple pour vérifier
si le port MySQL est ouvert ou non, est d'essayez la commande suivante
depuis une machine distante, où  
server_host
  est le serveur qui héberge
MySQL :  
Si vous obtenez une connexion et des caractères binaires, le port 
est ouvert, et il devrait être fermé par votre routeur ou votre coupe-feu,
à moins d'avoir une bonne raison pour le garder ouvert. Si  
telnet
  
attend, ou que la connexion est refusée, tout va bien : le port est bloqué.| 
shell> telnet server_host 3306
 | 
Ne faîtes confiance à aucune donnée entrée par les utilisateurs de votre
application. Ils peuvent déjouer vos filtres en entrant des séquences
spéciales via les formulaires Web, les URL ou tout autre point d'entrée
de l'application. Assurez vous que votre application reste sûre si un utilisateur
entre une chaîne telle que `` 
; DROP DATABASE mysql;
 ''. C'est un exemple
extrêmement simple, mais il dévoilera un trou de sécurité important. Il engendrera
aussi des pertes de données si un pirate, utilisant cette technique, vous
attaque.
 
Une erreur courante est de ne protéger que les chaînes de caractères. N'oubliez
pas de protéger aussi les valeurs numériques. Si une application génère une
requête telle que  
SELECT * FROM table WHERE ID=234
  où l'utilisateur
fournit le  
234
 , alors ce dernier peut proposer la valeur 
 
234 OR 1=1
  pour conduire à la requête 
 
SELECT * FROM table WHERE ID=234 OR 1=1
 . Par conséquent, le serveur
va lire toutes les lignes de la table. Cela va diffuser toutes les lignes
de votre application, et générer un trafic excessif. Pour vous prémunir contre
ce type d'attaque, ajoutez toujours des guillemets autour des constantes 
numériques :  
SELECT * FROM table WHERE ID='234'
 . Si un utilisateur entre
des informations supplémentaires, elles seront intégrées dans la chaîne. Dans 
un contexte numérique, MySQL supprimera automatiquement les caractères incompréhensibles.
Parfois, les gens pensent que si une base de données contient des informations
publiques, elle n'a pas besoin d'être défendue. C'est faux. Même si vous pouvez
accéder à toutes les lignes de la table, il faut toujours se prémunir contre 
les dénis de service (par exemple, en utilisant la technique ci-dessus pour 
générer un trafic excessif). Sinon, votre serveur sera inutilisable.Liste de vérification : 
Essayez d'entrer des caractères  
'''
  et  
'"'
  dans tous vos formulaires Web.
Si vous obtenez une erreur MySQL, étudiez immédiatement le problème.
Essayez de modifier une URL dynamique en ajoutant les séquences 
 
%22
  ( 
'"'
 ),  
%23
 
( 
'#'
 ) et  
%27
  ( 
'''
 ).
Essayez de modifier les types de données des URL dynamiques de numériques
en textuels, avec les caractères cités ci-dessus. Votre application doit être
sécurisée contre ce type d'attaque.
Essayez d'entrer des caractères, des espaces et d'autres symboles spéciaux,
autre que des nombres, dans un champ numérique. Votre application devrait 
supprimer tous ces caractères avant de les passer à MySQL, ou générer une erreur.
Passer à MySQL des valeurs non vérifiées est très dangereux.
Vérifiez la taille des chaînes avant de les passer à MySQL.
Essayez de faire connecter votre application en utilisant un autre nom
que celui qui est utilisé pour les tâches d'administration. Ne donnez
pas à votre application des droits dont elle n'a pas besoin.
De nombreuses interfaces de programmation disposent de moyens pour
protéger les valeurs. Correctement utilisés, ils évitent aux utilisateurs
de l'application de faire passer des caractères qui auront un effet
différent de celui attendu :  
MySQL C API :
Utilisez la fonction  
mysql_real_escape_string()
 .
MySQL++ :
Utilisez les options  
escape
  et  
quote
  dans le flux de requête.
PHP :
Utilisez la fonction  
mysql_escape_string()
 , qui est basée sur
la fonction C du même nom. Avant PHP 4.0.3, utilisez   
addslashes()
 .
Perl  
DBI
  :
Utilisez la méthode  
quote()
  ou utilisez les variables de requête.
Java JDBC :
Utilisez un objet  
PreparedStatement
  ou utilisez les variables de requête. 
Les autres interfaces ont des fonctionnalités similaires.
Ne transmettez pas de données déchiffrées sur Internet. Cette information est
accessible à tout ceux qui ont le temps et la capacité d'intercepter et 
d'utiliser ces mots de passe. Utilisez plutôt un protocole sécurisé comme
SSL ou SSH. MySQL supporte les connexions SSL depuis la version 4.0.0.
SSH peut être utilisé pour créer un tunnel chiffré et compressé de communication.
Apprenez à utiliser les programmes  
tcpdump
  et  
strings
 . Dans la
plupart des cas, vous pouvez vérifier si un flux MySQL est chiffré avec
la commande suivante :  
(Cette commande fonctionne sous Linux, et devrait être adaptée facilement
dans les autres systèmes.)  Attention : si vous ne voyez pas de données 
en clair, cela ne signifie pas toujours que les informations sont chiffrées. 
Si vous avez besoin de haute sécurité, consultez un expert.| 
shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings
 | 
 |