Le meilleur regex pour attraper l'attaque XSS (Cross-Site Scripting) (en Java)?
Jeff a effectivement posté à ce sujet dans Sanitize HTML. Mais son exemple est en C# et je suis en fait plus intéressé par une version Java. Est-ce que quelqu'un a une meilleure version pour Java? Son exemple est-il suffisant pour convertir directement de C# en Java?
[mise à Jour] j'ai mis une prime sur cette question, parce que ce n'était pas aussi populaire quand j'ai posé la question comme elle l'est aujourd'hui (*). En ce qui concerne la sécurité, plus les gens s'y intéressent, mieux c'est!
(*) en fait, je pense qu'il était encore en beta fermée
8 réponses
ne faites pas cela avec des expressions régulières. Rappelez-vous, vous ne protégez pas seulement contre HTML valide; vous protégez contre le DOM que les navigateurs web créent. Les navigateurs peuvent être piégés dans la production de DOM valide à partir de HTML invalide assez facilement.
par exemple, voir cette liste de obscurci les attaques XSS. Êtes-vous prêt à adapter un regex pour empêcher cette attaque du monde réel sur 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<SCRIPT DEFER>alert("XSS")</SCRIPT>">
</BODY></HTML>
Comment à ce sujet une attaque qui marche sur IE6?
<TABLE BACKGROUND="javascript:alert('XSS')">
quid des attaques qui ne sont pas répertoriées sur ce site? Le problème avec L'approche de Jeff, c'est que ce n'est pas une liste blanche, comme on le prétend. Comme quelqu'un sur cette page habilement notes:
le problème avec cela, est que le html doit être propre. Il y a des cas où vous pouvez passer dans piraté html, et il ne correspond pas, dans quel cas il va retourner la chaîne HTML piratée comme elle ne correspondent à rien de ce à remplacer. Ce n'est pas strictement une liste blanche.
je dirais un outil comme AntiSamy. Il fonctionne en analysant réellement le HTML, puis en traversant le DOM et en enlevant tout ce qui n'est pas dans le configurable liste blanche. La principale différence est la capacité de traiter gracieusement HTML malformé.
la meilleure partie est qu'il est en fait des tests unitaires pour toutes les attaques XSS sur le site ci-dessus. En outre, ce qui pourrait être plus facile que cette API appel:
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();
}
The Open Web Application Security Project (OWASP) voici quelques suggestions pour assainir vos données. Voir par exemple:
Je ne suis pas convaincu que l'utilisation d'une expression régulière est la meilleure façon de trouver tout le code suspect. Les expressions régulières sont assez faciles à tromper spécialement lorsqu'il s'agit de HTML cassé. Par exemple, l'expression régulière listée dans le lien HTML Sanitize ne supprimera pas tous les éléments 'a' qui ont un attribut entre le nom de l'élément et l'attribut 'href':
< a alt="XSS injection" href = "http://www.malicous.com/bad.php">
Une façon plus robuste de supprimer du code malveillant est de s'appuyer sur un analyseur XML qui peut gérer tous les types de documents HTML (Tidy, TagSoup, etc.) et de sélectionner les éléments à supprimer avec une expression XPath. Une fois que le document HTML est divisé en un document DOM, les éléments pour revome peuvent être trouvés facilement et en toute sécurité. C'est même facile à faire avec XSLT.
j'ai extrait de NoScript best Anti-XSS addon, 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\/]|['"])(?: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]*=
Test:http://regex101.com/r/rV7zK8
je pense que c'bloquer 99% XSS parce que c'est une partie de NoScript, un addon qui me mis à jour régulièrement
le plus gros problème en utilisant le code jeffs est le @ qui n'est pas disponible actuellement.
je serais probablement juste prendre le "raw" regexp de jeffs code si j'en avais besoin et le coller dans
http://www.cis.upenn.edu/~matuszek/General/RegexTester/regex-tester.html
et voir les choses qui ont besoin de s'échapper s'échapper et puis l'utiliser.
en tenant compte de l'usage de ce regex, Je m'assurerais personnellement que compris 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 essayer de vous aider.
(c'est propbably assez judicieux conseils pour tout copier/coller)
[\s\w\.]*
. S'il ne correspond pas, vous avez XSS. Peut-être. Notez que cette expression ne permet que les lettres, les nombres et les périodes. Il évite tous les symboles, même utiles, par crainte de XSS. Une fois que vous autorisez &, vous avez des soucis. Et simplement remplacer toutes les instances de & par &
n'est pas suffisant. Trop compliqué à croire :P. évidemment cela va rejeter beaucoup de texte légitime (vous pouvez juste remplacer tous les caractères non matching avec un ! ou quelque chose), 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, mais peut-être que cela sera utile pour d'autres utilisateurs. Il y a un maintenu la couche de sécurité de l'outil 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