Initiation à la sécurité des Web Services

Avec l’expansion des services en lignes via le cloud ou tout simplement l’interconnexion des SI, le besoin d’exposer des services vers l’extérieur est croissant. Les WebServices sont une solution maintenant éprouvée depuis longtemps pour répondre à ce besoin.

Que l’on utilise SOAP ou REST un problème se pose toujours : comment faire pour sécuriser l’accès à mon SI alors que j’en ouvre une porte en exposant mon métier ?
Souvent utilisés au sein même d’un SI pour gérer des problématiques d’intégration ou d’hétérogénéité des technologies, les Web Services sont aussi de plus en plus souvent exposés sur le web ou à des partenaires.

Lorsque c’est possible, on voit souvent la mise en place d’un canal sécurisé type VPN entre les différents acteurs. Toutefois cela n’est pas toujours possible et cet article a pour but de vous présenter des notions de base liées à la sécurité des web services.

Ayant réalisé des missions, pour OCTO, aussi bien d’architecture que de développement autour ce sujet je vais tenter, via une série d’articles, de vous initier à ce domaine.
La majorité des WebServices de nos clients étant en SOAP je me concentrerais beaucoup plus sur ces derniers.
Cet article se voulant une initiation je ne suis pas rentré dans des détails très techniques, il a uniquement pour but d’attirer l’attention sur la vulnérabilité des protocoles de Web Services.

Identifier le besoin et les risques

Lorsqu’on traite de sécurité il faut toujours commencer par se poser quelques questions

  1. Mes données sont elles sensibles?
  2. Quel est le risque et quelles sont les conséquences pour mon SI si ces données sont capturées ou utilisés à mauvais escient ?
  3. Quelle est la probabilité que quelqu’un attaque mon service ?

Sans rentrer dans les détails de l’analyse de risque qui sort du périmètre de cet article, il est important d’avoir une bonne idée de la réponse à ces questions pour ensuite être capable de déterminer le niveau de sécurité nécessaire.

Valider les données

Une des failles de sécurité qu’on croise le plus dans les applications concerne les points d’entrée des données. Que ce soit un formulaire sur une page web ou un web service, tout point d’entrée de donnée vers votre application est potentiellement une faille de sécurité.
Il est donc essentiel et critique de valider tout ce que les utilisateurs de votre application pourront envoyer à celle-ci.
En effet un WebService est aussi vulnérable qu’un formulaire à l’injection SQL (passage de morceaux de requêtes SQL à un champ de donnée pour les faire interpréter par le serveur) et à d’autres exploit du même acabit. Pour plus de détails je vous invite à consulter cette page de l’OWASP.
De plus, la majorité des WebService utilisant SOAP et donc du XML sont vulnérables à toutes les failles induites par XML.

La validation des données entrées est donc critique pour éviter de nombreuses failles. Pour cela il existe de nombreux moyens.
Première étape, utiliser un WSDL particulièrement stricte sur le typage des données et sur la taille des champs vous protégera déjà de nombreux problèmes.
De la même manière je ne peux rentrer dans les détails sans trop m’étendre, mais la mise en place de DTD, voir mieux de XSD, est un très bon levier.
En effet l’adresse d’un DTD étant indiquée dans le XML, un utilisateur mal attentionné pourra la modifier dans le message qu’il vous envoi, pour changer la méthode de validation des données par celle de son choix (beaucoup plus permissive). Dans le cas d’un XSD seul le serveur sait quel XSD utiliser pour valider le contenu.
Pour les champs spécifiques (adresse email, url…) utiliser des expressions régulières stricte pour valider est une bonne pratique.
Enfin, réfléchissez toujours bien à l’impact des données que l’utilisateur peut vous envoyer et donc manipuler.

Avant de vous présenter quelques failles induites par les WebServices SOAP, je tiens à rappeler qu’il est très facile pour un utilisateur mal intentionné de forger des messages SOAP avec des outils tels que soapUI. A la base conçu pour tester les WebServices cet outil s’avère formidable pour les attaquer en forgeant des messages.

SOAP & XML

Quelques attaques de type DoS (Denial of Service)

Buffer Overflow

SOAP a le gros avantage d’être un protocole très souple, ce qui est une qualité indéniable mais aussi un gros défaut en terme de sécurité.
La souplesse de SOAP réside essentiellement dans la possibilité d’encapsuler à peu près ce que l’on veut (tant que c’est un XML valide) dans un message SOAP.
Premier problème : aucune contrainte de taille.
Ce type d’attaque est généralement couvert par le framework de WebService que vous utilisez (sauf si celui-ci est vraiment obsolète).
Néanmoins un utilisateur mal intentionné qui souhaite réalise un DoS (Denial Of Service) sur votre application pourra s’amuser à essayer d’envoyer un message énorme à vos WebService pour tenter de faire planter le parseur XML qui va démarshaller le message SOAP.
C’est bien entendu les parseurs de type DOM qui chargent tout le message XML en mémoire avant de l’interpréter qui sont vulnérable à ce type de problèmes.
Ce type d’attaque amène à un problème de type BufferOverflow qui induit souvent au plantage complet de l’application.

Il est donc crucial de vérifier la taille des messages reçus avant de tenter de les interpréter.

Récursion infinie

Il s’agit ici d’envoyer un XML récursif au web service. Si le parseur est de type XPath il va partir en boucle infinie.
Exemple :

1
<credit><credit><credit>….

D’autres attaques …

XML Injection

L’idée ici est plutôt d’outrepasser les validateurs de données pour détourner l’usage prévu du Web Service.

Un exemple bien parlant :

1
2
3
4
5
6
7
<transaction> 
<total>4000.00<total>
<credit_card_number>123456789</credit_card_number> 
<total>6.66</total>
<credit_card_number>123456789 </credit_card_number> 
<expiration>17112010</expiration>
</transaction>

En répétant la balise total, l’attaquant tente de changer les valeurs démarshallées par le Web Service pour ainsi payer 6,66 au lieu de 4000 euros. Cet exemple est volontairement simpliste mais, croyez moi, je suis déjà tombé sur des cas ou cela fonctionne.

XPath Injection

L’idée ici est d’attaquer les parseurs de type XPath. En effet si vos requêtes XPath se basent sur les entrées utilisateurs le parseur risque d’interpréter des choses non prévus :

Exemple :
//users/custid[123] va aller récupérer l’utilisateurs ayant pour ID 123, ici l’utilisateur bienveillant à bien mis son Id donc tout va bien.

//users/custid[./age > 1] va aller récupérer tous les utilisateurs dont l’âge est supérieur à 1, ici l’utilisateur malveillant à tenté de mettre un bout de XPath en paramètre et le résultat est assez facile à deviner :)

L’index de requête étant passé en paramètre cela autorise l’utilisateur à utiliser un identifiant client différent du sien. Il est ainsi libre de récupérer les données de tous les utilisateurs de l’application.

Failles XML & SOAP : comment s’en prémunir

Globalement la réponse est très simple : ne réinventez pas la roue.
D’une part pour tout ce qui touche au parsing XML utilisez des frameworks éprouvés et testés par les communautés Open Source par exemple. En réécrivant un parseur XML vous prenez le risque de ne pas penser à tous les types d’attaques présentés précédemment et bien entendus à tous ceux qui ne sont pas exposés ici.
Les frameworks existants sont testés par de nombreux utilisateurs, dont certain très avertis vont remonter ce type de problèmes qui seront très vite corrigés.
Il en va de même pour votre framework de WebService. Utilisez un framework éprouvé et ne réinventer pas la roue en branchant votre parseur XML maison à une socket en écoute sur le port 80. Je caricature mais parfois on croise des choses terrifiantes … Et bien entendu validez tout ce que votre application recevra via des messages SOAP.

Enfin mettez à jour vos frameworks. Les mises à jours de ceux ci (même mineures) incluent souvent des correctifs au failles de sécurités mises en évidences.
Bref à retenir : utilisez des frameworks de parsing XML et de Web Services modernes et éprouvés par la communauté.

Côté réseau et hardware : HTTP, HTTPS, VPN, filtrage IP, filtrage hardware

Une question qui m’est souvent remontée est : quelle type de transport utiliser pour exposer mes Web Services ?

Déjà je tiens à briser un a priori souvent entendu : exposer vos services sur le web en HTTPS ne vous prémunit pas de tous les risques.
Au mieux vous vous protéger des attaques du type man in the middle (et donc qu’un utilisateur intercepte vos messages), mais toutes les autres attaques restent possible.
Il est néanmoins important de savoir que SSL peut, comme un VPN, assurer l’authentification de l’utilisateur si le serveur est correctement configuré.
Cependant, par défaut les canaux cryptés n’ont qu’un seul intérêt : garantir la confidentialité de l’échange. C’est à dire qu’un utilisateur en écoute sur vos échanges ne pourra pas les intercepter (confidentialité de l’échange).
C’est donc très important mais très souvent insuffisant.
Il est toutefois possible de mettre en place une authentification HTTP Basic ou WS Basic devant un WebService via une configuration spécifique du serveur. Néanmoins ces méthodes d’authentification sont peu fiable car le mot de passe circule en clair il est donc interceptable. Donc ces types d’authentification restent tout à fait valables si elles sont utilisées sur un canal crypté.

Les tunnels de type VPN sont déjà un cran au dessus car ils assurent l’authentification de l’appelant (souvent grâce à un certificat) via l’accès VPN. Cela vous protège aussi des écoutes malveillantes car les tunnels VPN sont cryptés. Cela vous apporte, en plus, une limitation sur les utilisateurs qui se connectent à vos services car seuls ceux que vous autorisez explicitement peuvent utiliser le canal VPN. Le canal VPN est donc une très bonne solution mais pas toujours applicable.

Le filtrage d’IP est une protection intéressante pour limiter les appelants de vos services, néanmoins il est relativement facile de masquer son adresse IP par une autre (spoofing d’adresse IP). C’est donc un levier de sécurité intéressant mais insuffisant à lui tout seul.
La mise en place de signature numérique sur les messages permet alors de valider la non répudiation de ceux-ci.

A noter qu’il existe aussi des solutions matérielles type Datapower pour gérer la sécurité de vos services selon les possibilités et la configuration du matériel choisi. Ces solutions sont particulièrement efficaces mais très couteuses. Dans un degrés de risque élevé elles sont toutefois justifiées. Ces solutions ont aussi l’avantage d’être particulièrement efficace pour accélérer la gestion du SSL, gérer l’authentification et les autorisations ainsi que la validation des données des flux.

GDIA : Gestion des identités et des accès.

On en revient finalement toujours au même, lorsque des données et services sont sensibles il est donc nécessaire de les protéger par deux mécanismes classiques : l’authentification et l’autorisation.
Néanmoins ce n’est pas toujours évident à mettre en place sur un Web Service, on ne peut pas simplement mettre un formulaire devant comme sur un site web.

SOAP dans sa souplesse, découpe ses messages en deux parties : un header et un body.
Le body est normalement prévu pour ne contenir que des notions orientées métier. Le header quand à lui est là pour recevoir toutes les notions techniques nécessaires au web service.
C’est donc lui que nous allons utiliser pour contenir les informations d’authentification et d’autorisation.
Les protocoles de sécurité de Web Service tel que WS Sécurity et ses consorts se basent tous sur ce header soap.

De manière un peu généraliste, une bonne pratique est de mettre en place un web service d’authentification. Celui lui ne sera pas filtré car il faut bien qu’il soit appelable la première fois. Il fournira des données de sécurité (comme un jeton unique à durée de vie limitée par exemple) à l’utilisateur qui se sera authentifié via une webmethod prévue à cet effet. L’utilisateur devra ensuite fournir (dans les header soap pour ne pas mélanger les notions techniques et métiers dans le message) son login et son mot de passe ou mieux, ce jeton de sécurité pour chaque appel à vos services métiers.
Côté WebService, un intercepteur devra valider ces données avant de permettre ou rejeter l’appel au service métier.
Cette bonne pratique est de manière très macroscopique le fonctionnement proposé par des protocoles tels que WS Security.

Concernant les mécanismes de gestion des autorisations, nous ne nous étendrons pas sur le sujet car cela peut être soit très simple (read/write ou user/admin) soit très complexe et nécessiter un article complet rien que sur le sujet. On peut toutefois facilement imaginer un intercepteur branché après l’authentification pour vérifier les droits de l’appelant.
Il est bon aussi de savoir qu’un protocole comme OAuth est tout à fait adapté pour gérer les autorisations d’accès à un WebService, d’autant qu’il est fortement compatible avec les services de type Rest qui sont orientés ressources.

Conclusion

Pour conclure il ne faut jamais oublier qu’un WebService est une porte d’entrée vers votre application. Le sécuriser est donc important.
La majorité des failles présentés dans cet article à titre informatif sont couvertes par les frameworks de WebService modernes (Pour java : CXF, Métro, JBossWS ….).
Néanmoins il est important de s’assurer de l’identité et des droits de l’appelant avant de le laisser appeler vos méthodes métiers.
Enfin le cryptage du canal d’échange, quelque soit le moyen, est un très bon levier de sécurité mais comme nous l’avons vu il ne mitige qu’une partie des risques.
La mise en place de signature numérique est aussi un élément aujourd’hui très fiable pour valider la non répudiation de vos messages.
Dans bien des cas, comme dit en introduction, une basic authentification HTTP sur un canal HTTPS s’avèrera suffisant et plus justifié que la mise en place d’outils évolués et relativement complexes à mettre en place tels que WS Security. Il faut donc bien mesurer le besoin et le confronter au risque avant de décider quel niveau de sécurité engager.
Toutefois n’oubliez pas que la notion la plus importante est toujours la validation des données envoyés par vos utilisateurs !

Dans un prochain article je vous présenterais les notions apportées par des protocoles de sécurité de web services tels que WS Security, XML Signature ou XML Encryption.

Mots-clés: , ,

2 commentaires pour “Initiation à la sécurité des Web Services”

  1. Si l’on décide de chiffré le canal de communication, il peut être intéressant d’utilisé HTTPS avec demande de certificat client par le serveur au lieu d’un VPN. Cela permet de récupérer plus facilement le « commun name » du certificat client (unique si les certificats sont créés correctement) et de l’utiliser comme identifiant, limitant ainsi la possibilité pour un usager de modifier son identifiant et de récupérer des informations ne le concernant pas.

    Aussi, dans votre article les mots « cryptage » et « crypté » sont très utilisés, ces mots n’ont pas lieu d’être et peuvent induire une confusion avec les notions de déchiffrement (retrouver le message en clair à partir d’une clé) et de décryptage (retrouver le message en clair sans l’aide d’une clé).
    les mots « chiffrage » et « chiffré » seraient plus adaptés…

  2. Merci pour cet article fort intéressant.
    Que pensez-vous de SAML pour la sécurité des web services?

Laissez un commentaire