Pergunta

Jeff realmente postou sobre isso em Sanitizar HTML.Mas o exemplo dele está em C# e na verdade estou mais interessado em uma versão Java.Alguém tem uma versão melhor para Java?O exemplo dele é bom o suficiente para converter diretamente de C# para Java?

[Atualização] Eu coloquei uma recompensa nesta pergunta porque SO não era tão popular quando fiz a pergunta como é hoje (*).Quanto a qualquer coisa relacionada à segurança, quanto mais pessoas se interessarem, melhor será!

(*) Na verdade, acho que ainda estava em beta fechado

Foi útil?

Solução

Não faça isso com expressões regulares.Lembre-se, você não está protegendo apenas contra HTML válido;você está se protegendo contra o DOM criado pelos navegadores da web.Os navegadores podem ser induzidos a produzir DOM válido a partir de HTML inválido com bastante facilidade.

Por exemplo, veja esta lista de ataques XSS ofuscados.Você está preparado para adaptar uma regex para evitar esse ataque do mundo real Yahoo e Hotmail no 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 tal esse ataque que funciona no IE6?

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

E quanto aos ataques que não estão listados neste site?O problema com a abordagem de Jeff é que não se trata de uma lista de permissões, como afirmado.Como alguém em aquela página observa habilmente:

O problema é que o HTML deve estar limpo.Há casos em que você pode passar no HTML hackeado, e ele não corresponde a ele; nesse caso, ele retornará a string html hackeada, pois não corresponde a nada para substituir.Isso não é estritamente na lista de permissões.

Eu sugeriria uma ferramenta desenvolvida especificamente como AntiSamy.Ele funciona analisando o HTML e, em seguida, percorrendo o DOM e removendo tudo o que não está no configurável lista branca.A principal diferença é a capacidade de lidar normalmente com HTML malformado.

A melhor parte é que ele testa todos os ataques XSS no site acima.Além disso, o que poderia ser mais fácil do que esta chamada de 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();
}

Outras dicas

Não estou muito convencido de que usar uma expressão regular seja a melhor maneira de encontrar todos os códigos suspeitos.Expressões regulares são muito fáceis de enganar, especialmente quando se lida com HTML corrompido.Por exemplo, a expressão regular listada no link Sanitize HTML não conseguirá remover todos os elementos 'a' que possuem um atributo entre o nome do elemento e o atributo 'href':

<a alt="injeção xss" href="http://www.malicous.com/bad.php" >

Uma maneira mais robusta de remover código malicioso é contar com um analisador XML que possa lidar com todos os tipos de documentos HTML (Tidy, TagSoup, etc) e selecionar os elementos a serem removidos com uma expressão XPath.Depois que o documento HTML é analisado em um documento DOM, os elementos a serem removidos podem ser encontrados com facilidade e segurança.Isso é ainda mais fácil de fazer com XSLT.

Extraí do NoScript o melhor complemento Anti-XSS, aqui está seu Regex:Trabalho impecável:

<[^\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]*=

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

Acho que bloqueia 99% do XSS porque faz parte do NoScript, um complemento que é atualizado regularmente

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

Isto irá validar caracteres, dígitos, espaços em branco e também o <br> marcação.Se você quiser mais risco, você pode adicionar mais tags como

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

O maior problema ao usar o código jeffs é o @ que atualmente não está disponível.

Eu provavelmente pegaria o regexp "bruto" do código jeffs se precisasse e colaria em

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

e ver as coisas que precisam de fuga escaparem e então usá-las.


Tendo em mente o uso desse regex, eu pessoalmente me certificaria de entender exatamente o que estava fazendo, por que e quais seriam as consequências se eu não tivesse sucesso, antes de copiar/colar qualquer coisa, como as outras respostas tentam ajudá-lo.

(Esse é provavelmente um bom conselho para qualquer copiar/colar)

[\s\w\.]*.Se não corresponder, você tem XSS.Talvez.Observe que esta expressão permite apenas letras, números e pontos.Evita todos os símbolos, mesmo os úteis, por medo do XSS.Depois de permitir &, você terá preocupações.E apenas substituindo todas as instâncias de & por &amp; não é suficiente.Muito complicado para confiar :P.Obviamente, isso não permitirá muitos textos legítimos (você pode simplesmente substituir todos os caracteres não correspondentes por !ou algo assim), mas acho que isso matará o XSS.

A ideia de apenas analisá-lo como html e gerar um novo html é provavelmente melhor.

Um tópico antigo, mas talvez seja útil para outros usuários.Existe uma ferramenta de camada de segurança mantida para php: https://github.com/PHPIDS/ É baseado em um conjunto de regex que você pode encontrar aqui:

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

Esta questão ilustra perfeitamente uma grande aplicação do estudo da Teoria da Computação.Teoria da Computação é um campo que se concentra na produção de representações matemáticas de computadores.

Algumas das pesquisas mais profundas na teoria da computação são as provas que ilustram as relações de várias linguagens.

Algumas das relações linguísticas que os teóricos da computação provaram incluem:

enter image description here

Isso mostra que as linguagens livres de contexto são mais poderosas que as linguagens regulares.Assim, se uma linguagem é explicitamente livre de contexto (livre de contexto e não regular), então é impossível qualquer expressão regular para reconhecê-lo.

JavaScript é, no mínimo, livre de contexto, portanto sabemos com cem por cento de certeza que projetar uma expressão regular (regex) capaz de capturar todos os XSS é uma tarefa impossível.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top