Apparemment, les attaques ReDos exploitent les caractéristiques de certaines expressions régulières (autrement utiles) ... provoquant essentiellement une explosion de chemins possibles à travers le graphique défini par le NFA.
Est-il possible d'éviter de tels problèmes en écrivant une expression rationnelle «non perverse» équivalente? Sinon (ainsi, la grammaire ne peut pas être gérée dans l'espace / temps pratique par un NFA), quelles approches d'analyse seraient mieux? Pourquoi?
regular-expressions
parsers
David Bullock
la source
la source
Réponses:
Cela dépend si vous avez une expression régulière ou une expression rationnelle: les expressions régulières sont mauvaises, mais les expressions régulières sont une chose de beauté et ne vous transformeront jamais en mal.
Par expression régulière, je veux dire une expression régulière moderne: c'est-à-dire une expression régulière avec des fonctionnalités modernes supplémentaires telles que les références arrières - par exemple, une expression régulière compatible Perl. Ceci est plus puissant qu'une expression régulière classique d'un manuel de théorie formelle des langages / automates, car les expressions régulières classiques ne permettent pas les références arrières, l'anticipation, la recherche, etc.
Pour une expression régulière classique, si vous avez une bonne implémentation pour le matcher, alors aucune expression régulière n'est trop mauvaise. En particulier, un algorithme standard de correspondance consiste à convertir l'expression régulière en NFA, puis à exécuter le NFA sur une chaîne d'entrée. Pour cet algorithme, le temps d'exécution le plus défavorable pour tester une chaîne de caractères est O ( n ) , lorsque l'expression régulière est fixe. Cela signifie que le temps de fonctionnement ne peut pas exploser trop rapidement. Aucune chaîne ne provoquera une augmentation exponentielle du temps d'exécution. Ainsi, si vous utilisez un matcher qui utilise cet algorithme, aucune expression régulière classique ne sera mauvaise.n O(n)
Cela dépend de l'implémentation de la correspondance d'expression régulière. Si vous avez une implémentation naïve ou médiocre de la correspondance, la correspondance peut prendre un temps exponentiel; il existe certainement des algorithmes avec cette propriété. Mais la meilleure réponse à cela n'est probablement pas de changer l'expression régulière; il est probablement préférable de choisir un meilleur match, si vous êtes préoccupé par les attaques par déni de service.
En comparaison, certains regexps modernes sont inévitablement mauvais. Si vous avez une expression rationnelle moderne, la correspondance peut nécessiter un temps exponentiel. En particulier, les expressions rationnelles avec des références arrières peuvent reconnaître les langages NP-hard. Par conséquent, sous des hypothèses plausibles, il existe une classe de regexps maléfiques où le test d'une correspondance prend un temps exponentiel. Ainsi, certaines expressions rationnelles modernes sont inévitablement mauvaises: il n'y a aucun moyen possible de trouver une expression rationnelle équivalente qui ne provoquera pas une explosion exponentielle en temps d'exécution.
(Un tel équivalent pourrait exister et pourrait même être trouvé en théorie, mais sous des hypothèses plausibles, trouver l'expression rationnelle équivalente prendra un temps exponentiel, ce qui n'est pas possible en pratique. Si vous aviez une procédure systématique pour trouver l'expression rationnelle équivalente en temps polynomial , alors vous pourriez résoudre le problème NP-difficile en temps polynomial, prouvant que P = NP. Il n'y a pas grand-chose de bon pour qu'il existe une expression rationnelle équivalente s'il n'y a aucun moyen de le trouver dans votre vie.)
Contexte et sources:
Quelles langues les expressions régulières compatibles Perl reconnaissent-elles? L' expressivité des expressions régulières modernes fournit des références pour justifier que les expressions rationnelles modernes peuvent reconnaître les langages NP-hard.
Comment simuler des références arrières, des anticipations et des arrière-plans dans des automates à états finis? et Quand une expression rationnelle n'est pas une expression régulière? peut être utile pour comprendre la différence entre les expressions régulières et les expressions rationnelles.
Cet article de Russ Cox a une belle explication de deux façons différentes de construire un adaptateur d'expression régulière et explique pourquoi le temps d'exécution si vous utilisez l'algorithme approprié est linéaire dans la longueur de la chaîne d'entrée (lorsque l'expression régulière est maintenue fixe et sa longueur est traitée comme une constante). En particulier, l'algorithme basé sur NFA - également connu sous le nom d'algorithme de Thompson - a un temps d'exécution linéaire dans le pire des cas. Il montre également comment certains langages populaires ont des implémentations d'expression rationnelle qui peuvent devenir exponentielles sur certaines expressions rationnelles, et il explique quels aspects des expressions régulières modernes peuvent introduire des temps d'exécution exponentiels.
Dans ce post, je suppose que P! = NP. Plus précisément, lorsque je fais référence à des "hypothèses plausibles", je fais référence à l' hypothèse de temps exponentiel .
la source
Cette réponse adoptera une vue plus globale de cette situation transversale inhabituelle, où la théorie de la complexité est applicable à la cybersécurité et l'exemple contient certaines des nuances / subtilités importantes qui peuvent se produire dans ce domaine. Ceci est essentiellement similaire à une "attaque par injection" où certaines entrées inattendues provoquent un comportement pathologique soit en plantant un système, soit en le faisant prendre un temps anormalement long.
Wikipedia a 15 catégories d' attaques par déni de service et cette attaque tombe dans "inondations au niveau des applications" dans cette liste. Un autre exemple quelque peu similaire est une attaque qui remplit les journaux des applications.
Un correctif pour les attaques par injection consiste à «nettoyer l'entrée». Le concepteur d'application peut réévaluer s'il est nécessaire de compiler des expressions rationnelles arbitraires fournies par un utilisateur potentiellement malveillant. Il suffit probablement de supprimer les expressions imbriquées dans l'expression rationnelle ou une autre limitation similaire pour éviter cette attaque. Bien qu'ils soient intrinsèques à de nombreux logiciels modernes, de grandes quantités de fonctionnalités peuvent être fournies sans évaluer les expressions régulières. Le contexte est important, certaines applications ne nécessiteraient pas une telle sécurité.
Une autre approche pour améliorer la tolérance aux pannes / la résilience qui s'applique ici est les délais d'expiration spécifiés à différents niveaux de la pile / hiérarchie logicielle. L'idée serait de spécifier un temps / cpu ou une limite d'instruction sur une évaluation d'expression régulière "moyenne" et de terminer tôt si elle est dépassée. Ils peuvent être implémentés avec des solutions personnalisées, mais peu de logiciels ou de langages de programmation ont des délais d'expiration ou des cadres intégrés à cet effet.
Voici un bel exemple de l'utilisation des délais d'attente pour améliorer la tolérance aux pannes et montre une conception / architecture / pov de haut niveau pour atténuer ces problèmes: Tolérance aux pannes dans un système distribué à haut volume / Netflix. Il n'a rien de spécifiquement lié aux expressions régulières, mais c'est le point ici: pratiquement toute logique de niveau application peut s'intégrer dans ce cadre ou quelque chose de similaire.
Cet article souligne comment le retour en arrière en particulier peut conduire à une correspondance d'expression rationnelle lente. Les regexps ont de nombreuses fonctionnalités différentes et on pourrait essayer d'évaluer celles qui conduisent aux comportements les plus défavorables.
Voici une belle étude scientifique de ce sujet particulier avec des solutions d' analyse statique proposées:
Analyse statique du temps d'exécution exponentiel à expression régulière via la logique sous-structurelle / Rathnayake, Thielecke
la source