Réalisation de sites web

Sommaire du site

Présentation
Comment apprendre
L'équipement
La page web
  Styles et CSS
  HTML, structure de la page
  HTML, éléments du corps
Le langage JavaScript
  JavaScript, objets "core"
  JavaScript, DOM, les bases
  JavaScript, DOM, node
  JavaScript, compléments
Le langage PHP, les bases
  PHP, fonctions utiles
  PHP pour le web
  PHP, compléments
SQL, introduction
  MySQL et PHP pour le web
  MySQL, plus loin...
Applications AJAX
Annexes utiles
  Fichier .htaccess
  Sécurité des sites web
  Conception d'un site web
  Référencement, syndication

Sommaire détaillé

Mentions légales.

Chapitres de cette page
Contenu  -> 

Page mise à jour le : 12-08-2015

Haut de la page

Principes de base
Les utilisateurs privilégiés
Types d'attaques
Le problème des robots
Les formulaires.
Le « pot de miel »
En savoir plus

Sécurité des sites web

Ce document présente les principales techniques d’attaque de site web. Celles-ci sont les plus répandues.

Naturellement, il est impossible de décrire toutes les possibilités d’intrusion car certaines ne sont pas encore bien connues.

Tout site web est accessible aux internautes du monde entier, surtout s’il est référencé par les moteurs de recherche.

Tout site est accessible à n’importe qui, mais en lecture seule. Eventuellement certains utilisateurs dûment authentifiés peuvent modifier son contenu. Il est évidement souhaitable que d’autres ne puissent pas en faire autant.

Malheureusement, il existe des internautes qui cherchent à détourner les sites web pour d’autres usages.

Voici leurs principales actions.

Les motivations sont donc souvent mercantiles mais certains piratent un site uniquement par jeu.

Il est donc toujours nécessaire de sécuriser au minimum le site.

Principes de base

Bien sûr un site web dédié à une association locale n’aura pas les mêmes risques qu’un site contenant des informations confidentielles ou de commerce. Cependant si le site est mal construit, il est sensible à son détournement. Par conséquent, quelle que soit la nature du site web, il faut penser à le sécuriser.

Evidement, la première sécurité est de ne pas divulguer les codes d’accès de bases de données et d'accès FTP du serveur. Il faut savoir que certains logiciels FTP tel FileZillia conservent ces codes en clair sur le disque du poste. De toutes façons, si l’ordinateur depuis lequel on utilise le FTP est partagé par plusieurs utilisateurs il ne faut pas que le mot de passe FTP soit enregistré par le logiciel.

Dans la mesure du possible, il faut utiliser sur le serveur les dernières versions des logiciels : serveur (Apache généralement), PHP et SQL. Les failles de sécurité découvertes de ces logiciels sont corrigées de version en version.

Dans le même ordre d’idées, il faut être prudent dans l’utilisation de scripts et d’applications tout prêts et connus que l’on trouve sur Internet comme les CMS, logiciels de mails et de forums. Comme leur code est connu, il est facile aux pirates d’en trouver les failles. Là aussi il vaut mieux utiliser les dernières versions.

Lors de la conception du site, les zones sensibles à protéger sont celles où l’utilisateur entre des informations, en particuliers les formulaires mais aussi l’URL des pages.

Pour les sites qui transfèrent des données confidentielles, il faut aussi se protéger d’attaques plus élaborées comme le vol de session ou l’attaque par "l’homme du milieu" (voir plus bas dans cette page).

Enfin, comme il n’est jamais trop tard pour bien faire, il est nécessaire de mettre en place un enregistrement des accès au site et l’observer régulièrement. Ainsi on est prévenu des tentatives d’accès anormales et donc les contrecarrer.

Les utilisateurs privilégiés

Souvent certains utilisateurs du site disposent de privilèges qui les autorisent à accéder à des données confidentielles et parfois à intervenir sur le contenu du site.

Certains sites mènent la vie dure à ces utilisateurs en leur demandant de produire des mots de passe impossibles à retenir (longs et avec lettres, chiffres et parfois symboles..), les obligeant à en changer fréquemment ou en maintenant des connexions de durée très courte.

Parfois l'effet contraire est produit. On a remarqué que certains écrivent les mots de passe sur un "post-it" collé à leur écran.

Il faut rester réaliste et ne pas donner à un utilisateur gérant des adhérents d'une association les mêmes contraintes qu'à un administrateur de documents confidentiels dans une entreprise.

Il reste cependant nécessaire de bien sensibiliser ces utilisateurs aux problèmes de sécurité :

Il faut aussi informer les utilisateurs privilégiés des attaques qu’ils risquent de subir par ingénierie sociale en particulier relativement au phishing (hameçonnage).

Types d'attaques

Injection SQL

Lorsque les données issues d’un formulaire sont transmises directement (sans contrôle ni protection) à une requête de base de données, on court le risque de laisser passer des requêtes fallacieuses.

Considérons un formulaire traditionnel de connexion avec demande du "login" et du mot de passe.

Ces informations sont transmises à la page de connexion où l’on exécute la requête de vérification :

$requete= "SELECT `id`, `info` FROM `utils`
   WHERE `login`='$login' AND `PASSE`=MD5('$passe')";

Quelques essais

Certains systèmes SQL admettent d’autres caractères pour définir un commentaire, par exemple les tirets ‘—‘ .

Supposons qu’un pirate, connaissant un login valide, le saisisse suivi d’apostrophe et du dièse et, comme mot de passe, n’importe quoi. Par exemple,

admin' #
essai

La requête sera alors

SELECT `id`, `info` FROM `utils`

  WHERE `login`='admin' #' AND `PASSE`=MD5('essai')

L’apostrophe termine la valeur du champ “admin” et le dièse est reconnu comme commentaire SQL. La partie mot de passe est donc ignorée dans la requête, le pirate est connecté.

De plus en plus fort, soit le login :

toto' OR 1=1  #

La requête devient

SELECT `id`, `info` FROM `utils`

  WHERE `login`='toto' OR 1=1 #' AND `PASSE`=MD5('essai')

Comme “1=1” est toujours vrai, il n’y a plus besoin de connaitre un login valide. L’utilisateur est connecté avec le premier compte trouvé dans la table.

Il pourrait être intéressant de connaitre la liste des utilisateurs

toto' OR 'X'='X' INTO OUTFILE './fichier.txt'#

Bien sûr on aura un message d’erreur car le résultat de la requête est envoyé dans le fichier « fichier.txt ». Celui-ci contiendra alors la liste des utilisateurs.

Or ce fichier n’est donc pas vraiment disponible. En effet, il est créé dans le répertoire de la base de données, donc non accessible directement. Cependant il suffit de le préfixer correctement pour le placer dans un répertoire accessible du site.

Comment se protéger

La méthode classique consiste à activer les « Guillemets magiques » ("magic_quotes") par le « php.ini » (si on a accès à la configuration du serveur). En principe cela est fait dans les configurations PHP4. Cette option échappe les guillemets, apostrophes et barres obliques saisies par les utilisateurs. Il n’y a donc plus de problème.

Toutefois cette option est déconseillée à partir de la version 5.3 de PHP et supprimée à partir de la version 6 ! En effet, ce que saisi l’utilisateur n’est pas toujours à destination de SQL donc il est désagréable de neutraliser certains caractères si l’on en a besoin dans les traitements. De plus, certains considèrent qu’une fois les « magic quotes » activés, les concepteurs ne se soucient plus de la sécurité.

Si cette option n’est pas activée, on échappe ces caractères avant la requête SQL, en utilisant des fonctions spécifiques telles que 'mysql_real_escape_string()' pour MySQL.

Attention aux données numériques

Très souvent le concepteur ne protège pas les données numériques dans une requête SQL en partant du principe qu’un nombre ne doit pas poser de problème. Or le pirate peut fort bien modifier le formulaire (le simuler depuis un autre site) afin qu’au lieu de transmettre un nombre celui-ci envoie un texte.

Une clause telle que :

WHERE num=$n

Est donc particulièrement sensible aux injections que l’on a pu voir. Si on tient à la conserver ainsi, il est nécessaire de faire en sorte que la variable « $n » soit bien un nombre, par exemple par :

$n= intval($n) ;

Qui produit un nombre entier.

On peut, de plus, vérifier que le formulaire vient bien du bon site en testant, depuis la page de traitement des données du formulaire, l'existence et le contenu de la variable : " $_SERVER['HTTP_REFERER'] "

XSS (Cross-Site Scripting)

Il s’agit, pour le pirate, d’insérer dans une page du site du code HTML ou le plus souvent du JavaScript.

L’exemple le plus évident est dans les forums ou tout internaute peut écrire une contribution. Si l’attaquant écrit dans une page de forum :

<script type="text/javascript">
window.location.href="http://www.farfelu.com"
</script>

Le lecteur de cette page obtiendra la page d’accueil du site « www.farfelu.com » dans la fenêtre du forum.

Il ne faut pas croire que les «magic_quotes » suffisent pour se protéger car le pirate peut utiliser des éléments HTML où les guillemets sont facultatifs

<form name=a>
<input name=b value=http://www.farfelu.com>
</form>
<script> window.location.href=document.a.b.value
</script>

Pour éviter cela il faut traduire les caractères spéciaux de l’HTML en entités HTML avec la fonction PHP 'htmlspecialchars()' ainsi le texte sera affiché tel qu’il a été saisi.

Une autre forme de XSS se trouve dans le cas de pages utilisant dans leur adresse comme données complémentaires une URL d’une autre page comme :

http://www.monsite.com/page.php?adr=www.monsite.com/autrepage.html

Par exemple, pour afficher « autrepage.html » dans une fenêtre ou cadre de la page actuelle.

Il est facile de modifier l’adresse depuis le navigateur par exemple en :

http://www.monsite.com/page.php?adr=www.douteux.com

Ainsi, cela donnera une page du site « www.douteux.com ». Et celui-ci ne peut pas connaitre la vraie adresse (IP) de celui qui utilise sa page car c'est celle du serveur « www.monsite.com ».

Cette dernière technique est bien utilisée dans les messages non sollicités ("spam" et "phishing") ou le destinataire reçoit un message l’invitant à cliquer sur un lien. Il croit ainsi accéder à un site alors qu’il en verra un autre.

Pour se prémunir de ces usages fallacieux, il convient de vérifier soigneusement la valeur du paramètre transmis dans l’adresse avant de l'utiliser.

Vol de session

Les sessions permettent la mémorisation d’informations qui seront utilisées par plusieurs pages. Souvent la session contient les caractéristiques d’un utilisateur connecté comme ses droits d’accès. Il est donc tentant pour un pirate d’utiliser la session d’un utilisateur habilité afin de bénéficier de ses privilèges.

Rappel sur le mécanisme des sessions

Les informations de session sont généralement placées dans un fichier dont le nom est l’identificateur de session. Celui-ci est généré automatiquement comme « e259ce88455ab2854e714a70b9323227 » afin de permettre d’avoir des sessions différentes pour les utilisateurs connectés. Ce fichier de session est automatiquement détruit au bout d’un certain délai après sa dernière utilisation selon la configuration de PHP.

Si l’utilisateur accepte les cookies, l’un d’entre eux conserve le numéro de session (il sera détruit à la fermeture du navigateur), sinon il faut transmettre l’identificateur de session dans les URL des pages afin que le serveur puisse le retrouver.

Possibilités d’attaques

Elles sont délicates car il est difficile pour le pirate de trouver un identificateur de session valide. Cependant s’il accède à la machine d’un utilisateur en son absence, il peut retrouver l’identificateur de session dans les cookies où dans l’historique s’il était transmis par l’URL. Mais il faut agir avant que la session ait expirée sur le serveur.

Une autre possibilité est d’utiliser le XSS (Cross-Site Scripting) afin de diriger l’utilisateur vers une page d’un site malicieux qui au moyen du JavaScript récupère l’identificateur de session).

Minimum de protection

Il faut faire en sorte que les utilisateurs disposants de privilèges utilisent obligatoirement le cookie de session et que celui-ci soit détruit en fin d’accès au site. En effet, l’identificateur de session dans l’URL reste dans l’historique du navigateur alors que le cookie de session est détruit à la fermeture du navigateur.

Il faut aussi que les utilisateurs ferment leur session (se déconnectent) lorsqu’ils n’ont plus besoin du site où qu’ils quittent tous les exemplaires de leur navigateur. En effet, certains navigateurs conservent le cookie de session tant qu’une de leurs instances est en cours.

Certain propose un lien "se déconnecter" sur leurs pages qui supprime les informations de session.

S’il est possible d’intervenir dans la configuration du serveur. Vérifier que les identificateurs de session sont transmis par les cookies (si possible) et que le délai de conservation du fichier de session ne soit pas trop élevé.

L’homme du milieu

Les données des formulaires sont transmises telles quelles au serveur. Un  pirate peut accéder au réseau et observer les informations qui y passent voire les modifier, c’est « l’homme du milieu ».

En général les sites personnels et associatifs ne présentent que peu d’intérêt pour ce genre d’intrusion qui n’est pas à la portée de tous. Toutefois si des informations importantes circulent il vaut mieux se protéger.

Il s’agit de crypter les informations avant de les transmettre au serveur, charge à lui de les décrypter. Il existe tout un ensemble de « codes secrets » assez sûr pour cela, le plus connu étant RSA. Bien que l’on trouve également facilement des scripts de codage et de décodage, il est souvent nécessaire d’avoir quelques connaissances en cryptographie pour les adapter à sa situation.

Une solution plus simple mais onéreuse consiste à utiliser le protocole HTTPS. Du côté du navigateur, il n’y a pas de problème car ils savent tous le gérer. Il reste à trouver un serveur qui accepte ce protocole et à acheter un certificat afin de pouvoir l’utiliser.

C'est aussi rassurant pour l'utilisateur de voir dans sa barre d'adresse indiqué le protocole 'https'. De plus certains navigateurs vérifient aussi que l'adresse du site correspond bien au certificat.

Le problème des robots

Il y a deux sortes de robots : les bons et les mauvais.

Les bons sont ceux des moteurs de recherche, évidement si l’on souhaite qu’ils connaissent notre site. On n’en parle pas ici.

Les mauvais sont ceux des pirates qui essayent (désespérément ?) d’intervenir dans note site voire d’épuiser le serveur.

Comme il l’a été dit en introduction, il est indispensable de faire une observation sérieuse des accès au site afin de détecter ceux qui semblent louches.

Là encore le point sensible est le formulaire.

La méthode classique pour éviter qu’un robot remplisse le formulaire est d’utiliser un « Captcha ». Il s’agit le plus souvent d’une image contenant sur un fond assez chargé quelques caractères bien tordus que l’utilisateur doit saisir dans un champ du formulaire.
Cela pose quelques problèmes : les utilisateurs ayant une vue déficiente auront du mal à identifier les caractères et tous seront irrités. Une autre technique consiste à poser une question du type « Quel est la couleur du cheval blanc d’Henri IV ? » ou « Combien font 3+15 ». Toutefois certains robots arrivent à répondre car la liste des questions n’est pas infinie. Il existe aussi la version sonore du captcha, encore faut-il que l’utilisateur puisse l’entendre (équipement son).

On peut toutefois éliminer facilement les  robots qui adressent directement la page d’exploitation du formulaire sans passer par lui en vérifiant, lors de l’exploitation du formulaire, quelle page l’a appelée (variable $_SERVER['HTTP_REFERER']). Ce n'est pas infaillible car certains dispositifs remplissent automatiquement le vrai formulaire.

Dans le cas d’attaques répétées sur le site le mieux est d’en interdire l’accès à certaines adresses IP (celles qui attaquent) par le fichier « .htaccess », par exemple :

deny from .ru .ua .cn

Pour interdire l’accès aux utilisateurs venant de Russie, Ukraine ou Chine.

Ou :

RewriteCond %{REMOTE_ADDR}  ^194\.8\.7[4-5]
RewriteRule ^.*   -   [F]

Pour interdire l’accès aux utilisateurs dont l’adresse IP est comprise entre « 194.8.74.0 » « 194.8.75.255 » donc venant du réseau « DRAGONARA-NET » des Iles Vierges britanniques.

Il est possible de placer sur son site un fichier texte nommé 'robot.txt' dont le but est de d'interdire l'accès de certaines pages du site à certains robots.

Si cela convient bien aux "gentils robots", il est évident que les méchants ne prendront pas ce fichier en considération.

Il en est de même en ce qui concerne la ligne HTML :
<META NAME="robots" CONTENT="noindex">

 

Encore quelques conseils concernant les formulaires

Messages d’erreur

Eviter pour les requêtes SQL d’afficher en cas d’erreur un message donnant la totalité de la requête. Il n’est pas utile de faire connaître la structure de la table.

Formulaire de connexion

Il est préférable de ne pas lier la page contenant le formulaire de connexion au site : pas de lien de type « se connecter » et pas de formulaire de connexion non plus dans les pages accessibles du site.
Placer le formulaire de connexion sur une page spéciale, non liée au site et inconnue des moteurs de recherche. Seuls ceux qui ont à se connecter connaitront son adresse. Pour vivre heureux, vivons cachés.

A l’exploitation du formulaire de connexion, il est intéressant de rechercher le login de l’utilisateur par une requête et, si elle aboutit, vérifier le mot de passe par une seconde requête. Cela évite les injections qui cherchent à tromper le mot de passe par des informations complémentaires fournies dans le champ « login ».

Formulaire d’envoi de messages

Au sujet des adresses électroniques

Il ne faut jamais donner une adresse électronique valide dans une page HTML (même non affichée par le navigateur), dans ce cas 'spam' garanti.

Certains "maquillent" les adresses :
toto CHEZ martin.com

D'autres les remplacent par une image contenant l'adresse.

Souvent, un formulaire est destiné à l’envoi de message (mail) généralement à l’administrateur du site voire aux contributeurs. Cela évite d’insérer des adresses électroniques dans les pages du site (source de SPAM).

Il faut être très prudent sur la gestion de ces formulaire afin qu’ils ne puissent pas être utilisés pour générer des courriers non sollicités, auquel cas le gestionnaire du site en serait responsable.

En particulier le destinataire du message doit être défini uniquement à l’exploitation du formulaire (et non pas comme champ caché dans celui-ci).

Une surveillance précise des messages envoyés doit être mise en place afin de voir les éventuels détournements, par exemple avec enregistrement dans une base de données ou envoi d’une copie à un gestionnaire du site.

Si l’expéditeur doit recevoir une copie de ce qu’il a saisi, il lui est proposé d'indiquer son adresse électronique dans un champ du formulaire. Il faut vérifier que ce champ ne contient qu’une adresse et pas une cinquantaine.

Ce type de formulaire est aussi une porte d’entrée pour des attaques par ingénierie sociale.

Forums publics

Beaucoup de prudence car comme le texte de la contribution sera affiché c’est un bon endroit pour le XSS. Outre ce qui a été déjà dit dans le chapitre concernant le XSS il est nécessaire de vérifier que les contributions sont conformes à l’éthique du site. La modération des contributions d’impose, au moins à postériori. Il est utile d’envoyer le texte des contributions par messagerie électronique aux modérateurs afin qu’ils puissent, le cas échéant les supprimer du site.

Pour les curieux : le « pot de miel » (honeypot)

Comme les techniques de piratage de site sont très variées et évoluent, il peut être intéressant de se rendre compte par soi-même des méthodes d’attaques utilisées.

Le « pot de miel » est un piège destiné à attirer les pirates et ainsi à connaitre leurs techniques.

Par exemple on peut placer sur le site un formulaire « Se connecter ». Mais ce formulaire ne permet pas de connexion véritable, il sert uniquement à enregistrer les tentatives. Ainsi par l’exploitation de ces données on peut connaitre les techniques utilisées pour entre frauduleusement dans le site. Et, bien sûr, vérifier que le vrai formulaire de connexion (bien caché) déjoue de tels essais.

Cela ne dispense pas de mettre ses connaissances à jour régulièrement en consultant les sites web spécialisés.

En savoir plus...

Une petite sélection de sites web traitant de ces sujets.

Vulnérabilité informatique sur Wikipédia
http://fr.wikipedia.org/wiki/Vuln%C3%A9rabilit%C3%A9_%28informatique%29
Sécurité en PHP sur php.net
http://www.php.net/manual/fr/security.php
Injection SQL
http://adsltele.free.fr/tutoriel-injection-sql.php
Vols de session
http://www.xmcopartners.com/article-owasp-session.html
Ingénierie sociale
http://www.commentcamarche.net/contents/attaques/ingenierie-sociale.php3