![]() |
|||||
Sécurité applicative dans les développements de technologies Internet : la Grande Oubliée ! |
|||||
Dire que la sécurité doit être appréhendée de manière globale et que la sécurité d'un système d'informations est comme la résistance d'une chaîne, c'est-à-dire égale à la résistance de son maillon le plus faible, sont des lieux communs dont sont convaincus la plupart des responsables sécurité. En fait, ces deux déclarations ont le même objectif. La première met en relief l'importance de la cohérence globale à apporter à une démarche sécuritaire et permettre ainsi d'identifier, comme le précise la seconde, les zones d'ombres qui doivent être traitées en priorité. Un des points fondamentaux est donc d'arriver à identifier précisément le ou les maillons faibles. Dans la gestion de la sécurité, l'accent est souvent porté sur la partie infrastructure d'une architecture globale, mise en œuvre d'équipements de filtrage ou d'analyse de flux (firewall, sondes de détection d'intrusions, ...), au détriment de la sécurité applicative ! C'est pourquoi je souhaite développer dans ces colonnes, ce que je nomme la Grande Oubliée de la sécurité informatique : la sécurité applicative. Pour beaucoup, sécuriser une application Web revient simplement à y accéder en https. Il n'en est absolument rien ! Rappelons que https offre deux principaux services. Il permet tout d'abord d'authentifier le serveur web auprès des utilisateurs finaux y accédant par utilisation et vérification par le navigateur du certificat serveur émis par une autorité de certification de confiance. Https permet, de plus, de garantir la confidentialité des échanges entre les navigateurs et le serveur, par utilisation d'une communication chiffrée (le niveau de sécurité du chiffrement dépendant de la longueur de la clé de chiffrement utilisée). Il peut aussi, mais ceci est encore peu déployé, être utilisé par le serveur pour authentifier l'utilisateur qui se connecte, ce dernier devant être alors muni d'un certificat.
Contrairement aux applications client/serveur « classiques » ou aux accès gros systèmes, l'accès aux applications Web ne s'effectue pas en mode connecté au niveau de la couche de communication elle-même. Dans les applications client/serveur traditionnelles, l'application cliente se connecte à l'application serveur sur un port TCP particulier et reste connectée tout le long de la session applicative. Un environnement utilisateur est créé à l'établissement de la session, garantissant ainsi une certaine imperméabilité de l'environnement client. Dans les architectures Web, en revanche, il n'existe pas de mode connecté entre les clients et les serveurs inhérent. Les navigateurs clients dialoguent en http (version 1.0 ou 1.1, la version 1.1 permettant le multiplexage des requêtes http sans offrir pour autant un mode connecté au niveau applicatif) avec le frontal Web. Celui-ci dialogue avec le serveur d'applications (service pouvant être assuré par le frontal lui-même de manière plus ou moins complexe : pages php, asp, scriptes CGI,… )qui accède au serveur de données. Chaque requête http étant indépendante des autres. Il est nécessaire de mettre en œuvre un mécanisme de suivi dans le temps de la session d'un utilisateur. Une session avec un serveur Web est comme un repas dans un restaurant. Un même serveur s'occupe d'un ensemble de tables et de clients distincts. Pour garantir le suivi entre la prise de commande et le service des plats commandés, le serveur écrit la commande sur une fiche qui lui servira de repère et lui permettra de faire le lien entre les plats préparés en cuisine et les différentes tables à servir. Ainsi, dans le monde Web, le mécanisme le plus utilisé pour effectuer le suivi de session est le cookie de session (l'autre mécanisme classique est l'utilisation de paramètres passés dans les URL mais le principe reste le même). Il s'agit en particulier des cookies ASPSESSIONIDxxxxxxxx, JSESSIONID, SITESERVER, PHPSESSID, CFID/CFTOKEN, WebLogicSession,… Le cookie de session est au serveur Web ce que la fiche de commande est au garçon de café. Ainsi, prendre le cookie de session d'une session active à un instant donné sur le serveur, revient à prendre la fiche de commande de la table voisine pour espérer consommer une raie aux câpres à la place d'un steack-frites ! Cela est en fait pire dans le monde Web, car au restaurant, il y a de grandes chances que le serveur se souvienne de la commandeou que votre voisin ne cautionne pas votre manipulation alors que dans le monde Web, l'utilisateur dont vous aurez pris la session peut très bien ne se rendre compte de rien. Il est alors possible d'accéder à l'ensemble des informations de l'utilisateur sans aucune authentification. Prenons l'exemple simple d'une application Extranet permettant à un responsable des achats de récapituler tous les achats effectués par sa société auprès d'un fournisseur. Il peut connaître les achats des différentes entités de son entreprise qui ont chacune un numéro de compte spécifique auprès de ce fournisseur. Après s'être authentifié, la page d'accueil du site présente la liste des différents comptes et, en sélectionnant un compte, il obtient le détail des achats. Pour suivre la session, un cookie de session est donné au navigateur (qui sera donc présenté par le navigateur à chaque requête vers le serveur) au moment de l'authentification. La capture de ce cookie (nom et valeur en particulier) peut permettre potentiellement à n'importe quelle autre personne, en présentant ce cookie et en précisant l'URL d'accueil du site Extranet, d'obtenir directement la liste des comptes et donc des achats correspondant à ce client. Il est donc capital que le cookie de session ne soit pas prédictible et qu'il soit véhiculé en https lors de l'accès à des données confidentielles. Dans ce dernier cas, il est de plus nécessaire que le cookie soit sécurisé, c'est-à-dire qu'il ne soit envoyé au serveur que quand le flux est du https, ce qui est rarement mis en œuvre : ![]() En effet, si le cookie n'est pas sécurisé et qu'un même serveur supporte à la fois du trafic http et https, le cookie non sécurisé sera transmis au serveur dans les deux types de flux sachant que lorsqu'il est transmis dans du trafic non chiffré, il peut être intercepté et lu. Sa capture peut alors permettre d'accéder à la session utilisateur comme précisé ci-dessus.
Comme je l'ai évoqué précédemment, les architectures web classiques font intervenir différents composants, en particulier, les frontaux web, les serveurs d'applications et les serveurs de données. De manière classique aussi, le serveur d'applications accède au serveur de données en utilisant un unique utilisateur vis à vis de la base de données. Ainsi, cet utilisateur aura souvent les droits maximum sur la base de données (lecture/écriture sur la quasi totalité des tables de la bases). Cependant un client final de l'application ne devra accéder qu'aux seules informations le concernant. L'authentification de l'utilisateur s'effectuant au niveau du frontal Web ou du serveur d'application, il est indispensable que des contrôles particuliers soit mis en œuvre vérifier la cohérence entre l'authentification de l'utilisateur et ses droits sur les données. Pour reprendre l'exemple du responsable des achats, une fois authentifié, la liste des différents comptes qu'il possède auprès du fournisseur s'affiche et la sélection d'un compte présente le détail des achats. Si le lien de l'affichage du détail du compte contient simplement le numéro du compte passé en paramètre dans l'URL et qu'il n'y a pas de vérification que ce responsable peut bien interroger ce compte, il peut être possible, en modifiant le numéro de compte de l'URL d'interroger un compte se rapportant à une autre société. Il est donc fondamental de parfaitement corréler l'authentification de l'utilisateur et ses droits sur les données.
Une application Web possède en général de nombreux formulaires permettant d'effectuer des interrogations ou saisir des données. Il est indispensable que les données saisies par l'utilisateur final soit analysées avant d'être traitées. De manière plus précise, deux risques classiques peuvent se présenter :
Les architectures Web présentent intrinsèquement des risques nouveaux aussi bien au niveau des infrastructures que des applications elles-mêmes et c'est souvent à propos de ces dernières que les connaissances sont les plus faibles. Pour réduire au maximum ces risques, il est important que la problématique sécurité soit abordée dès la phase de conception des applications, le surcoût ainsi engendré pouvant être réduit, et, de toutes façons, sans commune mesure avec les impacts sur les coûts et les délais en cas d'une prise en compte a posteriori. Une solution consiste, par exemple, à imposer une charte de développements sécurisés traitant aussi bien les risques génériques transversaux liés aux architectures applicatives web que les spécificités liées aux langages ou aux composants de développement utilisés. Il est capital de garder à l'esprit que plus la prise en compte de la problématique sécurité se fait tardivement dans le cycle de vie d'un projet, plus les impacts négatifs sont importants. Cependant, pour les applications existantes, il n'est pas forcément possible d'intervenir directement sur ces dernières, pour cela, l'utilisation de firewalls applicatifs reste la meilleure solution. Laurent Charvériat |
|||||
|