7. Considérations de sécurité (Security Considerations)
Cette section décrit les domaines potentiels de préoccupation en matière de sécurité avec HPACK :
-
Utilisation de la compression comme oracle basé sur la longueur pour vérifier des suppositions sur des secrets qui sont compressés dans un contexte de compression partagé.
-
Déni de service résultant de l'épuisement de la capacité de traitement ou de mémoire d'un décodeur.
7.1. Sondage de l'état de la table dynamique (Probing Dynamic Table State)
HPACK réduit la longueur des encodages de champs d'en-tête en exploitant la redondance inhérente aux protocoles comme HTTP. L'objectif ultime de ceci est de réduire la quantité de données nécessaire pour envoyer des requêtes ou des réponses HTTP.
Le contexte de compression utilisé pour encoder les champs d'en-tête peut être sondé par un attaquant qui peut à la fois définir des champs d'en-tête à encoder et transmettre et observer la longueur de ces champs une fois qu'ils sont encodés. Lorsqu'un attaquant peut faire les deux, il peut modifier de manière adaptative les requêtes afin de confirmer des suppositions sur l'état de la table dynamique. Si une supposition est compressée en une longueur plus courte, l'attaquant peut observer la longueur encodée et en déduire que la supposition était correcte.
Cela est possible même sur le protocole TLS (Transport Layer Security) (voir [TLS12]), car bien que TLS fournisse une protection de confidentialité pour le contenu, il ne fournit qu'une quantité limitée de protection pour la longueur de ce contenu.
Note : Les schémas de remplissage ne fournissent qu'une protection limitée contre un attaquant disposant de ces capacités, ne forçant potentiellement qu'un nombre accru de suppositions pour apprendre la longueur associée à une supposition donnée. Les schémas de remplissage fonctionnent également directement contre la compression en augmentant le nombre de bits transmis.
Des attaques comme CRIME [CRIME] ont démontré l'existence de ces capacités générales d'attaquant. L'attaque spécifique a exploité le fait que DEFLATE [DEFLATE] supprime la redondance basée sur la correspondance de préfixe. Cela a permis à l'attaquant de confirmer les suppositions un caractère à la fois, réduisant une attaque en temps exponentiel en une attaque en temps linéaire.
7.1.1. Applicabilité à HPACK et HTTP (Applicability to HPACK and HTTP)
HPACK atténue mais ne prévient pas complètement les attaques modelées sur CRIME [CRIME] en forçant une supposition à correspondre à une valeur de champ d'en-tête entière plutôt qu'à des caractères individuels. Les attaquants ne peuvent apprendre que si une supposition est correcte ou non, ils sont donc réduits à des suppositions par force brute pour les valeurs de champs d'en-tête.
La viabilité de la récupération de valeurs de champs d'en-tête spécifiques dépend donc de l'entropie des valeurs. Par conséquent, les valeurs avec une entropie élevée sont peu susceptibles d'être récupérées avec succès. Cependant, les valeurs avec une faible entropie restent vulnérables.
Des attaques de cette nature sont possibles chaque fois que deux entités mutuellement méfiantes contrôlent des requêtes ou des réponses qui sont placées sur une seule connexion HTTP/2. Si le compresseur HPACK partagé permet à une entité d'ajouter des entrées à la table dynamique et à l'autre d'accéder à ces entrées, alors l'état de la table peut être appris.
Avoir des requêtes ou des réponses provenant d'entités mutuellement méfiantes se produit lorsqu'un intermédiaire soit :
-
envoie des requêtes de plusieurs clients sur une seule connexion vers un serveur d'origine, ou
-
prend des réponses de plusieurs serveurs d'origine et les place sur une connexion partagée vers un client.
Les navigateurs Web doivent également supposer que les requêtes effectuées sur la même connexion par différentes origines Web (voir [ORIGIN]) sont effectuées par des entités mutuellement méfiantes.
7.1.2. Atténuation (Mitigation)
Les utilisateurs de HPACK peuvent prendre des mesures pour limiter le potentiel de sondage de la table dynamique en restreignant la capacité des entités mutuellement méfiantes à ajouter des entrées à la table dynamique et à observer l'état de la table dynamique.
L'atténuation la plus efficace consiste à éviter de partager des connexions ou des contextes de compression entre des requêtes ou des réponses qui ne sont pas le résultat d'actions de la même origine.
Pour les intermédiaires, cela signifie que les requêtes de différents clients et les réponses de différents serveurs d'origine NE DOIVENT PAS (MUST NOT) partager un seul contexte de compression HPACK.
Pour les agents utilisateurs, cela signifie que les contextes de compression DOIVENT (MUST) être séparés pour les requêtes à différentes origines qui ne sont pas connues pour être sous contrôle commun.
7.1.3. Littéraux jamais indexés (Never-Indexed Literals)
Les implémentations peuvent également choisir de protéger les champs d'en-tête sensibles en ne les compressant pas et en encodant plutôt leur valeur sous forme de littéraux.
Refuser de générer une représentation indexée pour un champ d'en-tête n'est efficace que si la compression est évitée sur tous les sauts. Le bit de littéral jamais indexé (voir section 6.2.3) peut être utilisé pour signaler aux intermédiaires qu'une valeur particulière a été intentionnellement envoyée sous forme de littéral.
Un intermédiaire NE DOIT PAS (MUST NOT) ré-encoder un champ d'en-tête qui utilise la représentation de littéral jamais indexé avec une autre représentation qui l'indexerait. Si HPACK est utilisé pour le ré-encodage, une représentation littérale sans indexation (voir section 6.2.2) peut être utilisée à la place.
Le choix d'utiliser une représentation de littéral jamais indexé pour un champ d'en-tête dépend de plusieurs facteurs. Étant donné que HPACK ne protège pas contre la supposition d'une valeur de champ d'en-tête entière, les valeurs courtes ou de faible entropie sont plus facilement récupérées par un adversaire. Par conséquent, un encodeur pourrait choisir de ne pas indexer les valeurs avec une faible entropie.
Un encodeur pourrait également choisir de ne pas indexer les valeurs pour les champs d'en-tête considérés comme hautement précieux ou sensibles à la récupération, tels que les champs d'en-tête Cookie ou Authorization.
7.2. Encodage de Huffman statique (Static Huffman Encoding)
Il n'existe actuellement aucune attaque connue contre un encodage de Huffman statique. Une étude a montré que l'utilisation d'une table d'encodage de Huffman statique créait une fuite d'informations ; cependant, cette même étude a conclu qu'un attaquant ne pourrait pas tirer parti de cette fuite d'informations pour récupérer une quantité significative d'informations (voir [PETAL]).
7.3. Consommation de mémoire (Memory Consumption)
Un attaquant peut tenter de faire en sorte qu'un point de terminaison épuise sa mémoire. HPACK est conçu pour limiter les quantités de mémoire allouées par un point de terminaison, à la fois au pic et de manière stable.
La quantité de mémoire utilisée par le contexte de compression peut être limitée en définissant une taille maximale pour la table dynamique. Dans HTTP/2, cela est contrôlé par le paramètre SETTINGS_HEADER_TABLE_SIZE (voir section 6.5.2 de [HTTP2]).
Un encodeur peut limiter la quantité d'état qui peut être créé chez un décodeur en contrôlant la taille de la table dynamique. Dans HTTP/2, cela est rapporté par le décodeur via l'utilisation du paramètre SETTINGS_HEADER_TABLE_SIZE. Un encodeur DOIT (MUST) limiter la taille de la table dynamique à la valeur rapportée par le décodeur, contrôlant ainsi la quantité de mémoire qui est engagée.
Un décodeur peut limiter la quantité de mémoire engagée dans la table dynamique en signalant une valeur SETTINGS_HEADER_TABLE_SIZE inférieure à la valeur par défaut. Dans HTTP/2, la valeur par défaut est de 4 096 octets, ce qui signifie que l'encodeur peut utiliser jusqu'à cette quantité de mémoire pour la table dynamique à moins que le décodeur ne modifie cela en envoyant un paramètre SETTINGS_HEADER_TABLE_SIZE dans une trame SETTINGS.
7.4. Limites d'implémentation (Implementation Limits)
Une implémentation doit définir une limite pour les valeurs qu'elle accepte pour les entiers et pour la taille des littéraux de chaîne. De la même manière, elle doit définir une limite au nombre d'entrées qu'elle stockera dans la table dynamique. Ne pas définir de limite pourrait exposer une implémentation à des attaques, similaires à ce qui a été observé dans les implémentations de protocole qui n'ont pas défini de limites raisonnables.