NF16618 — API ⇒ sécurisation du système de connexion pour se protéger des attaques de type ⇒ XSS CSRF

De Documentation Polaris
Aller à : navigation, rechercher

Voir la carte de la fonctionnalité : A classer



Pour protéger les API des problèmes standard de sécurité, nous avons choisi de mettre en place un système à secret échangé sur liaison TLS avec validation optionnelle du certificat par clé partagée AES256.

Dans la pratique, quatre informations sont impliquées dans l'identification d'un client pour nos API :

  • un identifiant unique (appelé dans le reste de la documentation UID ou GUID)
  • un secret (aka. l'équivalent d'un mot de passe très fort) ;
  • une clé AES partagée ;
  • l'empreinte du certificat du service ;

Ce document décrit le choix du système d'identification des API ainsi que les modalités d'installation, d'implémentation, et d'utilisation.

Afin de faciliter le travail des intégrateurs, il existe :

  • une documentation à jour pour la version du Polaris auquel vous vous connectez, disponible sur https://[service:client]:[port]/api/
  • le documentation est au format OpenApi permettant de générer les clients plus facilement.

Système à clé d'API (ou secret)

Beaucoup de systèmes utilisent un système de secret ou de clé d'API.

Le système est simple et efficace : à chaque requête, le client utilise son identifiant et son secret pour prouver son identité au service qui accepte le travail s'il trouve une correspondance dans sa base d'utilisateurs.

La preuve de l'identité se fait donc à chaque requête, par la communication d'un secret.

Mais ce système a une faiblesse : il est nécessaire pour le client d'identifier à coup sûr le service auquel il se connecte afin de ne pas envoyer ses informations de connexion à n'importe qui.

Explication : si un tiers venait à usurper l'identité du service, le client lui renverrait son secret sans se méfier (phishing). Le tiers pourra par la suite et à loisir utiliser cet accès sans que son véritable propriétaire en ait connaissance.

Pour contrer ce cas de figure, il est nécessaire d'établir la connexion sur une liaison TLS, protégée par un certificat X509 possédé par le service et reconnu expressément par le client.

Le fait que le certificat soit valide ne suffit pas, car de nombreuses autorités de confiance reconnues présentent des lacunes importantes dans le processus de validation du domaine (DCV) et peuvent délivrer par erreur à des adversaires des certificats (MITM attacks that use valid CA-issued certificates).

Muni de son certificat qui valide TLS, l'adversaire peut réaliser une attaque très simple par détournement de trafic pour récupérer la clé :


Attaque par MITM


Afin d'éviter ce cas dit de misissuance (i.e. une autorité de certification peu soigneuse tierce délivre par erreur à un adversaire un certificat valide pour le service) au moins une des trois techniques suivantes doit être impérativement mise en place.

Par restriction de certificat

L'idée générale est de mémoriser la clé partagée et l'empreinte du certificat du service à l'installation du client.

A la connexion, on vérifiera que le certificat est valide, mais également que son empreinte correspond bien à celle mémorisée. Si c'est le cas, alors on peut envoyer la clé partagée en toute sécurité.

C'est la méthode la plus simple et la plus efficace, mais également la plus contraignante car il est nécessaire de reconfirmer la clé partagée à chaque changement de certificat (tous les 3 mois pour Let's Encrypt, tous les ans pour Comodo). Tout certificat à clés suffisamment dimensionnées peut alors convenir.

Tout intégrateur est libre de la mettre en place à sa convenance mais nous n'assurons pas de support sur l'implémentation de la restriction.

Par restriction d'autorité de certification

L'idée générale ici est de mémoriser quelles sont les autorités de certification autorisées par le service à l'installation du client.

A la connexion, on vérifiera :

  • que le certificat présenté par le service est valide1;
  • qu'il n'a pas été révoqué par l'autorité qui l'a émit2;
  • mais également qu'une des autorités mémorisées est bien présente dans la chaîne de validation du certificat. Si c'est le cas, alors on peut envoyer la clé partagée en toute sécurité.

Cela fonctionne car le service n'accepte de travailler qu'avec les autorités de confiance :

Tout intégrateur est libre de la mettre en place à sa convenance mais nous n'assurons pas de support sur l'implémentation de la restriction.


1 cette opération est nativement prise en charge par votre OS et tous les clients HTTP

le contrôle de révocation CRL ou OCSP est souvent pris en charge de manière optionnelle, il convient de vérifier et d'activer la bonne option correspondant à votre bibliothèque.

Vérifier le certificat par défi à l'aide d'une clé partagée

C'est le niveau de sécurité optimal et c'est celui que nous avons choisi.

L'idée ici est de vérifier que le tiers nous présente bien un certificat qui correspond à celui que le service est censé utiliser et une fois vérifié, n'accepter les liaisons TLS que sur ce certificat (certificate pinning).

Rappelons nous que nous sommes dans le cadre d'une liaison TLS, ainsi, si interception il y a lieu, c'est forcement que l'adversaire est en possession d'un certificat valide du même nom que le service auquel nous nous connectons.

Puisque nous partageons normalement une clé secrète avec le serveur, nous allons nous en servir pour que ce dernier signe le certificat qu'il est censé utiliser. Ainsi, si un adversaire s'est placé entre les deux (attaque MiTM), il disposera d'un certificat valide, certes, mais pas de la clé partagée, il sera incapable de signer correctement son certificat et s'il laisse passer le trafic venant du service réel (hijack), le client constatera que le service a signé un autre certificat que celui sur lequel est établi sa liaison TLS.

Cette vérification est optionnelle et n'a besoin d'être effectuée que dans le cas où le certificat présenté par le serveur serait inconnu (à chaque fois qu'il change).


[SCHEMA à revoir : obsolète]


Déroulé de la phase de vérification du certificat

  1. le client envoi une demande avec son identifiant (UID) ;
  2. le service reçoit la demande, recherche la clé partagée correspondant à UID et l'utilise pour signer l'empreinte de son certificat avec le protocole HMAC-SHA256 ; puis renvoi cette signature ;
  3. le client effectue la même opération avec l'empreinte du certificat auquel il est connecté. Si les signatures sont égales, alors il s'agit bien du certificat autorisé et la communication peut continuer normalement ; autrement, la liaison doit être terminée et l'incident signalé.
  4. par la suite, seul le certificat qui a été autorisé devrait être accepté, les autres devraient être systématique rejeté (certificate pinning).

Détail de l'implémentation

<< todo >>

Considérations de sécurité

Pour le service

Note : les considérations de chiffrage de la clé ne sont pas implémentées pour le moment.

Comme les clés partagées sont stockées en base de données, celles-ci sont chiffrées avec une clé stockée sur un autre support de sorte qu'en cas de lecture indiscrète et non autorisée de la base de données, un adversaire ne puissent pas s'en emparer.

Pour des raisons évidentes de sécurité, la clé de déchiffrement n'est pas sauvegardée ni stockée au même endroit que les sauvegardes.

Le secret est stocké sous forme d'empreinte SHA256 (non déchiffrable).


Toute la sécurité nécessaire doit être prise lors de la communication initiale de la clé partagée et du secret. Si cet échange doit se faire par mail, alors il est plus que conseillé d'utiliser un envoi chiffré comme PGP.

Pour le client

Le client doit protéger la clé partagée et son secret par tout moyen possible. Si la clé et le secret sont stockés en base de données, ceux-ci devraient être chiffrés par une clé accessible sur un autre support que par le processus chargé de les utiliser de sorte qu'elle ne soit pas accessible à un adversaire arrivant à effectuer une lecture inappropriée de la base de données.

Échange des informations de connexion

Afin de permettre aux tiers de se connecter en toute sécurité sur le système sans envoyer les informations de connexion par mail, un processus de jumelage a été mis en place :

  • l'administrateur ouvre un accès et déclenche une procédure d'association depuis Polaris ;
  • un lien et un code PIN lui est fourni qu'il peut partager avec le fournisseur par mail ou téléphone ;
  • le lien n'est valable qu'une seule fois et permet d'obtenir les informations de connexion sur une liaison sécurisée en échange du code PIN.