Sécurité d'un site web

De WikiBR

Cette page liste les bonnes pratiques relatives à la sécurité à garder en mémoire lors du développement d'un site. Elles seront notamment examinées lors de l'audit de sécurité effectué par le BR avant d'ouvrir un site binet à l'extérieur.

Certificat SSL (HTTPS)

Un certificat SSL permet de chiffrer les échanges entre une machine accédant à votre site et le serveur. En son absence, les mots de passe circulent en clair !

NOTE : Le BR fournit à chaque site un certificat SSL reconnu par les navigateurs. Lors de l'ouverture du site à l'extérieur du Plâtal, tout le flux HTTP du site est redirigé vers du HTTPS dès lors que des informations sensibles circulent entre le client et le serveur.

Injections SQL

Il s'agit d'une insertion dans une requête SQL d'un morceau de requête non prévu par le système et pouvant en compromettre la sécurité.

NOTE : Si vous codez en PHP, le BR recommande l'utilisation de PDO, qui échappera les requêtes à votre place. Votre site sera protégé si vous utilisez correctement la méthode PDO::prepare().

NOTE : Si votre site est développé en Django et que vous utilisez des requêtes de type QuerySet, alors vous êtes correctement protégés.

ATTENTION : Si vous manipulez directement des requêtes SQL dans d'autres cadres que les précédents, assurez-vous de les échapper correctement.

Cross site scripting (XSS)

Cette attaque consiste en l’injection de données dans une page web dans le but de provoquer un comportement particulier du navigateur qui interprète cette page. Les données injectées ont donc la forme d’un langage interprété par le navigateur telles que des balises HTML ou du JavaScript. (source)

NOTE : Si votre site est développé en Django, vous êtes protégés. Il est toutefois recommandé de lire ce paragraphe de la documentation.

ATTENTION : Il faut s’assurer que toutes les données issues de sources externes qui sont incluses dans la page web sont protégées, c’est-à-dire leur faire subir un traitement qui empêche toute éventuelle interprétation comme du code.

Utilisez par exemple la fonction PHP htmlspecialchars() pour éviter que le texte ne soit interprété comme du contenu HTML. Cela ne protège toutefois pas des cas où l'inclusion se trouve dans un code javascript ou CSS par exemple.

Inclusion de fichiers

L’inclusion dynamique dans le code d’un lien vers une ressource dont le chemin d’accès dépend d’une entrée du client (par exemple en PHP echo '<a href## "http://example.com/?page .$page.'">mon lien</a>') n'est pas sûre. En choisissant certaines valeurs pour cette entrée, un attaquant peut chercher à exploiter ce fonctionnement pour amener l’application à inclure un fichier qu’il maîtrise et qui contient du code malveillant. Ce type d’attaques peut aussi servir à lire et à afficher le contenu de fichiers a priori inaccessibles sur le serveur par traversée de l’arborescence du système de fichiers. (source)

ATTENTION : Ne pas employer d'inclusion de fichiers dans le nom où le chemin d’accès dépend d’une donnée rentrée par l'utilisateur.

Gestion des sessions (Cookies)

Les cookies doivent être envoyés uniquement par HTTPS (les attributs HTTPOnly et Secure doivent être à la valeur vraie).

NOTE : En PHP, avant chaque appel à session_start(), mettre la ligne suivante : session_set_cookie_params(2*60*60, '/', 'votresite.binets.fr', true, true);

NOTE : En Django, mettre les valeurs suivantes de configuration à True dans le fichier settings.py : SESSION_COOKIE_HTTPONLY, SESSION_COOKIE_SECURE, CSRF_COOKIE_SECURE

NOTE : Avec Laravel (ou Lumen), modifier vendor/laravel/lumen-framework/config/session.php en mettant le paramètre secure à true, et ajouter la ligne suivante au début du fichier bootstrap/app.php : session_set_cookie_params(2*60*60, '/', 'votresite.binets.fr', true, true);

Stockage des mots de passe

Les mots de passe ne doivent pas être stockés en clair. Par ailleurs, l'utilisation d'un simple algorithme de hashage, comme md5 ou sha256, n'est pas suffisant. Il faut utiliser un sel>).

NOTE : En PHP, il est vivement recommandé d'utiliser les fonctions password_verify()]] (avec le paramètrePASSWORD_DEFAULT`) pour chiffrer le mot de passe et [[http://php.net/manual/fr/function.password-verify.php) pour vérifier que le mot de passe rentré par l'utilisateur correspondent bien au hash stocké.

NOTE : Avec Django, il est recommandé d'utiliser l'attribut password de l'objet User. Aucune intervention de la part du développeur n'est nécessaire, Django stocke correctement les mots de passe.

Protection contre le détournement de clic (clickjacking)

Le détournement de clic est un type d’attaque où un site malveillant intègre un autre site dans un cadre. Cette attaque peut amener un utilisateur à cliquer de manière non désirée pour effectuer des actions non volontaires sur le site ciblé. (source)

NOTE : Le BR ajoute à votre site une protection contre le détournement de clic en rajoutant dans les en-têtes de chacune de vos pages la directive X-Frame-Options: SAMEORIGIN. Aucune action n'est donc nécessaire de votre côté. :)

Mode debug

Le mode debug des bibliothèques tierce permet de corriger de nombreux bugs pendant la phase de développement. Toutefois, il laisse entrevoir des informations potentiellement compromettantes et utiles à un attaquant. Il faut le désactiver en passant en production.

NOTE : En Django, passer le paramètre DEBUG à False dans le fichier de configuration settings.py voir https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/ pour plus de détails.

NOTE : En Laravel, passer le paramètre APP_DEBUG à false dans le fichier .env

Si vous utilisez une autre bibliothèque tierce sur votre site, assurez-vous qu'elle ne soit pas en mode debug.