Je souhaite ajouter une fonction de recherche d'expression régulière à ma page Web publique. À part le codage HTML de la sortie, dois-je faire quelque chose pour me prémunir contre les entrées d'utilisateurs malveillantes?
Les recherches Google sont submergées par des personnes qui résolvent le problème inverse - en utilisant des expressions régulières pour détecter les entrées malveillantes - ce qui ne m'intéresse pas. Dans mon scénario, l'entrée utilisateur est une expression régulière.
J'utiliserai la bibliothèque Regex dans .NET (C #).
Réponses:
Problèmes de déni de service
La préoccupation la plus courante avec les expressions rationnelles est une attaque par déni de service via des schémas pathologiques qui deviennent exponentiels - voire super-exponentiels! - et semblent donc prendre une éternité à résoudre. Celles-ci ne peuvent apparaître que sur des données d'entrée particulières, mais on peut généralement en créer une dans laquelle cela n'a pas d'importance.
Ceux-ci dépendront quelque peu de l'intelligence du compilateur regex que vous utilisez, car certains d'entre eux peuvent être détectés pendant la compilation. Les compilateurs Regex qui implémentent la récursivité ont généralement un compteur de profondeur de récursivité intégré pour vérifier la non-progression.
L'excellent article de Russ Cox de 2007 sur la correspondance d'expressions régulières peut être simple et rapide (mais lent en Java, Perl, PHP, Python, Ruby, ...) parle des façons dont la plupart des NFA modernes, qui semblent tous dériver du code de Henry Spencer , souffrent d'une grave dégradation des performances, mais là où un NFA de style Thompson ne rencontre pas de tels problèmes.
Si vous n'admettez que des modèles qui peuvent être résolus par les DFA, vous pouvez les compiler en tant que tels, et ils s'exécuteront plus rapidement, voire beaucoup plus rapidement. Cependant, cela prend du temps . Le document de Cox mentionne cette approche et ses problèmes associés. Tout se résume à un compromis temps-espace classique.
Avec un DFA, vous passez plus de temps à le construire (et à allouer plus d'états), alors qu'avec un NFA, vous passez plus de temps à l'exécuter, car il peut s'agir de plusieurs états en même temps, et le retour en arrière peut manger votre déjeuner - et votre processeur.
Solutions de déni de service
La façon la plus raisonnable d'aborder ces modèles qui sont sur le côté perdant d'une course avec la mort par la chaleur de l'univers est de les envelopper avec une minuterie qui place effectivement un temps maximum alloué à leur exécution. Habituellement, ce sera beaucoup, beaucoup moins que le délai d'expiration par défaut fourni par la plupart des serveurs HTTP.
Il existe différentes façons de les implémenter, allant d'une forme simple
alarm(N)
au niveau C, à une sorte detry {}
blocage des exceptions de type alarme de capture, jusqu'à la création d'un nouveau thread spécialement créé avec une contrainte de synchronisation intégrée.Légendes de code
Dans les langages regex qui admettent les appels de code, un mécanisme pour autoriser ou interdire ceux-ci de la chaîne que vous allez compiler doit être fourni. Même si les légendes de code ne servent qu'à coder dans la langue que vous utilisez, vous devez les restreindre; ils n'ont pas besoin d'appeler du code externe, mais s'ils le peuvent, vous avez des problèmes beaucoup plus importants.
Par exemple, en Perl, on ne peut pas avoir d'appels de code dans les expressions régulières créées à partir d'une interpolation de chaîne (comme ce serait le cas, comme ils sont compilés pendant l'exécution) à moins que le pragma spécial à portée lexique soit
use re "eval";
actif dans la portée actuelle.De cette façon, personne ne peut se faufiler dans une légende de code pour exécuter des programmes système comme
rm -rf *
, par exemple. Parce que les légendes de code sont si sensibles à la sécurité, Perl les désactive par défaut sur toutes les chaînes interpolées, et vous devez faire tout votre possible pour les réactiver.Défini par l'utilisateur \ P {roperties}
Il reste une question plus sensible à la sécurité liée aux propriétés de style Unicode - comme
\pM
,\p{Pd}
,\p{Pattern_Syntax}
ou\p{Script=Greek}
- qui peuvent exister dans certains compilateurs regex que le soutien que la notation.Le problème est que dans certains d'entre eux, l'ensemble des propriétés possibles est extensible par l'utilisateur. Cela signifie que vous pouvez avoir des propriétés personnalisées qui sont de véritables appels de code vers des fonctions nommées dans un espace de nom particulier, comme
\p{GoodChars}
ou\p{Class::Good_Characters}
. La façon dont votre langue gère ces problèmes pourrait valoir la peine d'être examinée.Bac à sable
En Perl, un compartiment sandbox via le
Safe
module donnerait le contrôle sur la visibilité de l'espace de noms. D'autres langages proposent des technologies de sandboxing similaires. Si de tels périphériques sont disponibles, vous voudrez peut-être les examiner, car ils sont spécifiquement conçus pour une exécution limitée de code non approuvé.la source
Ajoutant à l'excellente réponse de tchrist: le même Russ Cox qui a écrit la page "Expression régulière" a également publié du code! re2 est une bibliothèque C ++ qui garantit une exécution O (length_of_regex) et une limite d'utilisation de la mémoire configurable. Il est utilisé dans Google afin que vous puissiez taper une expression régulière dans la recherche de code Google - ce qui signifie qu'il a été testé au combat.
la source
Oui.
Les expressions régulières peuvent être utilisées pour effectuer des attaques DOS .
Il n'y a pas de solution simple.
la source
Vous voudrez lire cet article:
Changement de contexte non sécurisé: inoculation d'expressions régulières pour la survie Le papier est plus sur ce qui peut mal tourner avec les moteurs d'expressions régulières (par exemple PCRE), mais il peut vous aider à comprendre ce à quoi vous êtes confronté.
la source
Vous devez non seulement vous soucier de la correspondance elle-même, mais également de la manière dont vous la faites. Par exemple, si votre entrée passe par une sorte de phase d'évaluation ou de substitution de commande sur son chemin vers le moteur d'expression régulière, il peut y avoir du code qui est exécuté à l'intérieur du modèle. Ou, si votre syntaxe d'expression régulière permet des commandes intégrées, vous devez également vous en méfier. Comme vous n'avez pas spécifié la langue dans votre question, il est difficile de dire avec certitude quelles sont toutes les implications en matière de sécurité.
la source
Un bon moyen de tester vos RegEx pour les problèmes de sécurité (au moins pour Windows) est l' outil de fuzzing SDL RegEx publié récemment par Microsoft. Cela peut aider à éviter une construction RegEx pathologiquement mauvaise.
la source