Question

Jeff a en fait posté à ce sujet dans Désinfecter le HTML.Mais son exemple est en C# et je suis en fait plus intéressé par une version Java.Quelqu'un a-t-il une meilleure version pour Java ?Son exemple est-il suffisant pour simplement convertir directement de C# en Java ?

[Mise à jour] J'ai mis une prime sur cette question car SO n'était pas aussi populaire lorsque j'ai posé la question qu'aujourd'hui (*).Quant à tout ce qui touche à la sécurité, plus les gens s’y intéressent, mieux c’est !

(*) En fait, je pense qu'il était encore en version bêta fermée

Était-ce utile?

La solution

Ne faites pas cela avec des expressions régulières.N'oubliez pas que vous ne vous protégez pas uniquement contre le code HTML valide ;vous vous protégez contre le DOM créé par les navigateurs Web.Les navigateurs peuvent être amenés à produire assez facilement un DOM valide à partir de HTML invalide.

Par exemple, consultez cette liste de attaques XSS obscurcies.Êtes-vous prêt à adapter une expression régulière pour empêcher cette attaque réelle contre Yahoo et Hotmail sur IE6/7/8 ?

<HTML><BODY>
<?xml:namespace prefix="t" ns="urn:schemas-microsoft-com:time">
<?import namespace="t" implementation="#default#time2">
<t:set attributeName="innerHTML" to="XSS&lt;SCRIPT DEFER&gt;alert(&quot;XSS&quot;)&lt;/SCRIPT&gt;">
</BODY></HTML>

Que pensez-vous de cette attaque qui fonctionne sur IE6 ?

<TABLE BACKGROUND="javascript:alert('XSS')">

Qu’en est-il des attaques qui ne sont pas répertoriées sur ce site ?Le problème avec l'approche de Jeff est qu'il ne s'agit pas d'une liste blanche, comme on le prétend.En tant que quelqu'un sur cette page note habilement :

Le problème avec cela, c'est que le HTML doit être propre.Il y a des cas où vous pouvez passer en html piraté, et il ne correspond pas, auquel cas il renverra la chaîne HTML piratée car elle ne correspondra à rien pour remplacer.Ce n'est pas une liste blanche strictement.

Je suggérerais un outil spécialement conçu comme AntiSamy.Cela fonctionne en analysant le HTML, puis en parcourant le DOM et en supprimant tout ce qui n'est pas dans le configurable liste blanche.La différence majeure réside dans la capacité à gérer avec élégance le HTML mal formé.

La meilleure partie est qu’il effectue des tests unitaires pour toutes les attaques XSS sur le site ci-dessus.D’ailleurs, quoi de plus simple que cet appel API :

public String toSafeHtml(String html) throws ScanException, PolicyException {

    Policy policy = Policy.getInstance(POLICY_FILE);
    AntiSamy antiSamy = new AntiSamy();
    CleanResults cleanResults = antiSamy.scan(html, policy);
    return cleanResults.getCleanHTML().trim();
}

Autres conseils

Je ne suis pas convaincu que l'utilisation d'une expression régulière soit le meilleur moyen de trouver tout le code suspect.Les expressions régulières sont assez faciles à tromper, surtout lorsqu'il s'agit de HTML défectueux.Par exemple, l'expression régulière répertoriée dans le lien Sanitize HTML ne parviendra pas à supprimer tous les éléments « a » qui ont un attribut entre le nom de l'élément et l'attribut « href » :

< a alt="injection xss" href="http://www.malicous.com/bad.php" >

Un moyen plus robuste de supprimer le code malveillant consiste à s'appuyer sur un analyseur XML capable de gérer toutes sortes de documents HTML (Tidy, TagSoup, etc.) et de sélectionner les éléments à supprimer avec une expression XPath.Une fois le document HTML analysé dans un document DOM, les éléments à révoquer peuvent être trouvés facilement et en toute sécurité.C'est même facile à faire avec XSLT.

J'ai extrait du meilleur addon Anti-XSS de NoScript, voici son Regex :Travail impeccable :

<[^\w<>]*(?:[^<>"'\s]*:)?[^\w<>]*(?:\W*s\W*c\W*r\W*i\W*p\W*t|\W*f\W*o\W*r\W*m|\W*s\W*t\W*y\W*l\W*e|\W*s\W*v\W*g|\W*m\W*a\W*r\W*q\W*u\W*e\W*e|(?:\W*l\W*i\W*n\W*k|\W*o\W*b\W*j\W*e\W*c\W*t|\W*e\W*m\W*b\W*e\W*d|\W*a\W*p\W*p\W*l\W*e\W*t|\W*p\W*a\W*r\W*a\W*m|\W*i?\W*f\W*r\W*a\W*m\W*e|\W*b\W*a\W*s\W*e|\W*b\W*o\W*d\W*y|\W*m\W*e\W*t\W*a|\W*i\W*m\W*a?\W*g\W*e?|\W*v\W*i\W*d\W*e\W*o|\W*a\W*u\W*d\W*i\W*o|\W*b\W*i\W*n\W*d\W*i\W*n\W*g\W*s|\W*s\W*e\W*t|\W*i\W*s\W*i\W*n\W*d\W*e\W*x|\W*a\W*n\W*i\W*m\W*a\W*t\W*e)[^>\w])|(?:<\w[\s\S]*[\s\0\/]|['"])(?:formaction|style|background|src|lowsrc|ping|on(?:d(?:e(?:vice(?:(?:orienta|mo)tion|proximity|found|light)|livery(?:success|error)|activate)|r(?:ag(?:e(?:n(?:ter|d)|xit)|(?:gestur|leav)e|start|drop|over)?|op)|i(?:s(?:c(?:hargingtimechange|onnect(?:ing|ed))|abled)|aling)|ata(?:setc(?:omplete|hanged)|(?:availabl|chang)e|error)|urationchange|ownloading|blclick)|Moz(?:M(?:agnifyGesture(?:Update|Start)?|ouse(?:PixelScroll|Hittest))|S(?:wipeGesture(?:Update|Start|End)?|crolledAreaChanged)|(?:(?:Press)?TapGestur|BeforeResiz)e|EdgeUI(?:C(?:omplet|ancel)|Start)ed|RotateGesture(?:Update|Start)?|A(?:udioAvailable|fterPaint))|c(?:o(?:m(?:p(?:osition(?:update|start|end)|lete)|mand(?:update)?)|n(?:t(?:rolselect|extmenu)|nect(?:ing|ed))|py)|a(?:(?:llschang|ch)ed|nplay(?:through)?|rdstatechange)|h(?:(?:arging(?:time)?ch)?ange|ecking)|(?:fstate|ell)change|u(?:echange|t)|l(?:ick|ose))|m(?:o(?:z(?:pointerlock(?:change|error)|(?:orientation|time)change|fullscreen(?:change|error)|network(?:down|up)load)|use(?:(?:lea|mo)ve|o(?:ver|ut)|enter|wheel|down|up)|ve(?:start|end)?)|essage|ark)|s(?:t(?:a(?:t(?:uschanged|echange)|lled|rt)|k(?:sessione|comma)nd|op)|e(?:ek(?:complete|ing|ed)|(?:lec(?:tstar)?)?t|n(?:ding|t))|u(?:ccess|spend|bmit)|peech(?:start|end)|ound(?:start|end)|croll|how)|b(?:e(?:for(?:e(?:(?:scriptexecu|activa)te|u(?:nload|pdate)|p(?:aste|rint)|c(?:opy|ut)|editfocus)|deactivate)|gin(?:Event)?)|oun(?:dary|ce)|l(?:ocked|ur)|roadcast|usy)|a(?:n(?:imation(?:iteration|start|end)|tennastatechange)|fter(?:(?:scriptexecu|upda)te|print)|udio(?:process|start|end)|d(?:apteradded|dtrack)|ctivate|lerting|bort)|DOM(?:Node(?:Inserted(?:IntoDocument)?|Removed(?:FromDocument)?)|(?:CharacterData|Subtree)Modified|A(?:ttrModified|ctivate)|Focus(?:Out|In)|MouseScroll)|r(?:e(?:s(?:u(?:m(?:ing|e)|lt)|ize|et)|adystatechange|pea(?:tEven)?t|movetrack|trieving|ceived)|ow(?:s(?:inserted|delete)|e(?:nter|xit))|atechange)|p(?:op(?:up(?:hid(?:den|ing)|show(?:ing|n))|state)|a(?:ge(?:hide|show)|(?:st|us)e|int)|ro(?:pertychange|gress)|lay(?:ing)?)|t(?:ouch(?:(?:lea|mo)ve|en(?:ter|d)|cancel|start)|ime(?:update|out)|ransitionend|ext)|u(?:s(?:erproximity|sdreceived)|p(?:gradeneeded|dateready)|n(?:derflow|load))|f(?:o(?:rm(?:change|input)|cus(?:out|in)?)|i(?:lterchange|nish)|ailed)|l(?:o(?:ad(?:e(?:d(?:meta)?data|nd)|start)?|secapture)|evelchange|y)|g(?:amepad(?:(?:dis)?connected|button(?:down|up)|axismove)|et)|e(?:n(?:d(?:Event|ed)?|abled|ter)|rror(?:update)?|mptied|xit)|i(?:cc(?:cardlockerror|infochange)|n(?:coming|valid|put))|o(?:(?:(?:ff|n)lin|bsolet)e|verflow(?:changed)?|pen)|SVG(?:(?:Unl|L)oad|Resize|Scroll|Abort|Error|Zoom)|h(?:e(?:adphoneschange|l[dp])|ashchange|olding)|v(?:o(?:lum|ic)e|ersion)change|w(?:a(?:it|rn)ing|heel)|key(?:press|down|up)|(?:AppComman|Loa)d|no(?:update|match)|Request|zoom))[\s\0]*=

Test: http://regex101.com/r/rV7zK8

Je pense qu'il bloque 99 % de XSS car il fait partie de NoScript, un module complémentaire mis à jour régulièrement.

^(\s|\w|\d|<br>)*?$ 

Cela validera les caractères, les chiffres, les espaces ainsi que les <br> étiqueter.Si vous voulez plus de risque, vous pouvez ajouter plus de balises comme

^(\s|\w|\d|<br>|<ul>|<\ul>)*?$

Le plus gros problème lié à l'utilisation du code Jeffs est le @ qui n'est actuellement pas disponible.

Je prendrais probablement simplement l'expression rationnelle "brute" du code de Jeffs si j'en avais besoin et la collerais dans

http://www.cis.upenn.edu/~matuszek/General/RegexTester/regex-tester.html

et voyez les choses qui ont besoin d'être échappées, puis utilisez-les.


En gardant à l'esprit l'utilisation de cette expression régulière, je m'assurerais personnellement de comprendre exactement ce que je faisais, pourquoi et quelles seraient les conséquences si je ne réussissais pas, avant de copier/coller quoi que ce soit, comme les autres réponses tentent de vous aider.

(C'est probablement un conseil assez judicieux pour tout copier/coller)

[\s\w\.]*.Si cela ne correspond pas, vous avez XSS.Peut être.Notez que cette expression n'autorise que les lettres, les chiffres et les points.Il évite tous les symboles, même utiles, par peur du XSS.Une fois que vous autorisez &, vous avez des soucis.Et simplement en remplaçant toutes les instances de & par &amp; c'est insuffisant.Trop compliqué de faire confiance :P.Évidemment, cela interdira beaucoup de texte légitime (vous pouvez simplement remplacer tous les caractères qui ne correspondent pas par un !ou quelque chose comme ça), mais je pense que ça va tuer XSS.

L'idée de simplement l'analyser en HTML et de générer un nouveau HTML est probablement meilleure.

Un vieux fil de discussion mais cela pourra peut-être être utile à d'autres utilisateurs.Il existe un outil de couche de sécurité maintenu pour PHP : https://github.com/PHPIDS/ Il est basé sur un ensemble de regex que vous pouvez trouver ici :

https://github.com/PHPIDS/PHPIDS/blob/master/lib/IDS/default_filter.xml

Cette question illustre parfaitement une grande application de l’étude de la théorie du calcul.La théorie du calcul est un domaine qui se concentre sur la production de représentations mathématiques des ordinateurs.

Certaines des recherches les plus approfondies en théorie du calcul concernent les preuves qui illustrent les relations entre divers langages.

Certaines des relations linguistiques prouvées par les théoriciens de l’informatique comprennent :

enter image description here

Cela montre que les langages sans contexte sont plus puissants que les langages classiques.Ainsi, si un langage est explicitement libre de contexte (libre de contexte et non régulier), alors il est impossible pour n'importe lequel expression régulière pour le reconnaître.

JavaScript est pour le moins sans contexte, nous savons donc avec une certitude à cent pour cent que concevoir une expression régulière (regex) capable de capturer tous les XSS est une tâche impossible.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top