(VRaptor) "Sanitizar" parametros para impedir ataques de XSS

Olá amigos do forum,

Preciso fazer algo no VRaptor para limpar os parametros recebidos no request, para evitar eventuais situações de XSS.

Minha idéia é usar esse cara -> https://www.owasp.org/index.php/Category:OWASP_AntiSamy_Project, mas ainda não estou sabendo o melhor lugar de implementar a limpeza…pensei em um interceptor ou um filtro, mas uma vez que os tais parametros estão limpos, o que é que eu faço? Não existe um método “setParameter” no HttpServletRequest :lol:

Pensei em fazer um request wrapper e sobrescrever o método getParameter, ai eu poderia fazer a limpeza lá dentro e sempre devolver o valor “limpo”. Seria uma boa?

Queria uma opinião dos colegas.

Obrigado!

Acho que você não deveria ter tanto trabalho para montar esse “sanitizator” afinal ele só vai ser utilizado para sanitizar campos que deveriam receber HTML ou CSS.
Na minha opinião, isso é especifico demais para generalizar.

Mikhas, acredito que qualquer campo de texto que o usuário preecha deve ser tratado.

Imagine por exemplo um campo para o nome da pessoa.
Após cadastrado esse nome aparecerá numa saudação qualquer dentro do sistema :

  <h2>Bom dia, {nome} </h2>

Se nessa variável {nome} tiver um script, isso pode te gerar problemas.

Em algum momento do processo entre armazenar e exibir, precisará validar isso.

alias, uma vez tentei fazer isso utilizando os Converters do Vraptor.
Criei um para String, mas não era chamado (provavelmente porque o valor por default já é string)
Na ocasião acabei criando um tipo para isso, para passar pela conversão, que efetuava o tratamento, e depois se transformado em string.
Como era algo pequeno, valeu a pena.
Num projeto maior não sei se essa abordagem é viável.

[quote=AbelBueno]Mikhas, acredito que qualquer campo de texto que o usuário preecha deve ser tratado.

Imagine por exemplo um campo para o nome da pessoa.
Após cadastrado esse nome aparecerá numa saudação qualquer dentro do sistema :

  <h2>Bom dia, {nome} </h2>

Se nessa variável {nome} tiver um script, isso pode te gerar problemas.

Em algum momento do processo entre armazenar e exibir, precisará validar isso.

alias, uma vez tentei fazer isso utilizando os Converters do Vraptor.
Criei um para String, mas não era chamado (provavelmente porque o valor por default já é string)
Na ocasião acabei criando um tipo para isso, para passar pela conversão, que efetuava o tratamento, e depois se transformado em string.
Como era algo pequeno, valeu a pena.
Num projeto maior não sei se essa abordagem é viável.

[/quote]

No caso de um campo de nome, idade, tipo, etc etc… Você deve fazer uma validação do dominio do valor do seu campo. Um campo de nome só pode conter letras e espaços, idade tem que ser numerico, o campo tipo é definido por um Enum XXX… Nesse caso, validators do vraptor se enquadram muito bem ou você pode usar Java Bean Validation (JSR 303).

Você tambem pode parar para pensar no overhead que o processo de sanitizar vai adicionar ao seu sistema. Isso não é um processo relativamente peve ou rapido o bastante para usar em todos ou grande parte dos campos. Validar é bem mais tranquilo.

E tem a complexidade que você esta tirando de um lugar e colocando em outro.

[quote=Mikhas][quote=AbelBueno]Mikhas, acredito que qualquer campo de texto que o usuário preecha deve ser tratado.

Imagine por exemplo um campo para o nome da pessoa.
Após cadastrado esse nome aparecerá numa saudação qualquer dentro do sistema :

  <h2>Bom dia, {nome} </h2>

Se nessa variável {nome} tiver um script, isso pode te gerar problemas.

Em algum momento do processo entre armazenar e exibir, precisará validar isso.

alias, uma vez tentei fazer isso utilizando os Converters do Vraptor.
Criei um para String, mas não era chamado (provavelmente porque o valor por default já é string)
Na ocasião acabei criando um tipo para isso, para passar pela conversão, que efetuava o tratamento, e depois se transformado em string.
Como era algo pequeno, valeu a pena.
Num projeto maior não sei se essa abordagem é viável.

[/quote]

No caso de um campo de nome, idade, tipo, etc etc… Você deve fazer uma validação do dominio do valor do seu campo. Um campo de nome só pode conter letras e espaços, idade tem que ser numerico, o campo tipo é definido por um Enum XXX… Nesse caso, validators do vraptor se enquadram muito bem ou você pode usar Java Bean Validation (JSR 303).

Você tambem pode parar para pensar no overhead que o processo de sanitizar vai adicionar ao seu sistema. Isso não é um processo relativamente peve ou rapido o bastante para usar em todos ou grande parte dos campos. Validar é bem mais tranquilo.

E tem a complexidade que você esta tirando de um lugar e colocando em outro.[/quote]

Obrigado pelas opiniões, colegas,

Mikhas, eu tendo a concordar com o colega AbelBueno. Uma validação de dominio não abrangeria a proteção contra ataques XSS. O exemplo que ele deu foi muito bom…afinal de contas, um script malicioso passaria em uma validação de “letras e espaços”, concorda? :wink: . Validar a integridade do dado do ponto de vista do modelo é mais tranquilo sim, mas não dá a segurança necessária.

AbelBueno, pensei nessa solução de criar um tipo específico pra isso que sempre devolvesse o valor limpo, mas dada a quantidade de classes onde teria que restringir isso acho que acabaria ficando meio macarronico. Parti pra implementação de um request wrapper que limpa o valor sempre que um parametro da requisicao é solicitado, depois vou postar o codigo pra aqui pra avaliação da geral.

E como disse o colega Mikhas há a questão do overhead que isso vai adicionar no tratamento da request…estou medindo isso tambem pra ver o impacto (certamente haverá algum)

Lembrei desse post antigo no blog da Caelum bacana sobre o assunto: http://blog.caelum.com.br/seguranca-em-aplicacoes-web-xss/

Obrigado amigos.

Não. Eu devo estudar técnicas de XSS, SQL injection entre outras maneira de “hackear” um site ou sistema e até hoje não vi uma maneira de realizar um XSS attack com um campo de texto simples como nome se este foi devidamente validado como eu disse.

Quero um exemplo por favor :wink:.

O que eu quero passar é que o AntiSamy é util sim, mas não para todos os casos. Ele deve ser usado para um input que você espera que contenha algum HTML ou CSS, outros campos devem ser tratados de maneira mais especifica e até mais simples!

[quote=Mikhas][quote=alias]
Mikhas, eu tendo a concordar com o colega AbelBueno. Uma validação de dominio não abrangeria a proteção contra ataques XSS. O exemplo que ele deu foi muito bom…afinal de contas, um script malicioso passaria em uma validação de “letras e espaços”, concorda? :wink: . Validar a integridade do dado do ponto de vista do modelo é mais tranquilo sim, mas não dá a segurança necessária.
[/quote]

Não. Eu devo estudar técnicas de XSS, SQL injection entre outras maneira de “hackear” um site ou sistema e até hoje não vi uma maneira de realizar um XSS attack com um campo de texto simples como nome se este foi devidamente validado como eu disse.

Quero um exemplo por favor :wink:.

O que eu quero passar é que o AntiSamy é util sim, mas não para todos os casos. Ele deve ser usado para um input que você espera que contenha algum HTML ou CSS, outros campos devem ser tratados de maneira mais especifica e até mais simples![/quote]

Bom, como não sou nenhum hacker acho que vou ficar devendo o exemplo :lol: , mas também sei que existem pessoas muito mais inteligentes que eu e com muito mais tempo livre que eu e que certamente teriam exemplos para nos mostrar. Compreendo seu ponto de vista e acho-o válido, mas estou preferindo pecar por excesso do que por “omissão”.

Para qualquer tipo diferente de string, acho que o Vraptor já faz um bom filtro inicial te fornecendo um valor tipado.

Em se tratando de string, não acho que poderá contar sempre com o domínio do valor daquele campo.
Limitar um nome de uma pessoa apenas as 26 letras coloca uma restrição artificial no sistema. (Impediria nomes com apóstrofo por exemplo).
Se levar em consideração outros nomes (produtos, empresas, etc) a variedades de símbolos permitidos aumentam ainda mais.

E provavelmente é mais simples uma solução global do que a cada objeto de domínio verificar se os valores permitem ou não xss.

Em relação ao overhead, imagino que seja um mal necessário mesmo.

esse AntiSamy project já não tem um filtro pronto? se tiver é só registrá-lo antes do filtro do VRaptor que dá tudo certo…

se não tiver, é fácil implementar esse filtro…

algo assim:

public class AntiSamiFilter implements Filter {
   //...
   //pseudocodigo
   doFilter(req, res, chain) {
      HttpServletRequest request = new HttpServletRequestWrapper((...) req) {
              @Override
               getParameter(name) => chama o super e aplica o anti-samy
              
                getParameterMap() => chama o super e aplica o anti samy em todo mundo
       };
      
       chain.doFilter(request, res);
   }

}

Opa galera, desculpem a demora pra dar um feedback. A implementação ficou mesmo como o Lucas sugeriu e eu tinha pensado inicialmente, com um request wrapper que retorna os parametros sanitizados. Pra quem mais precisar disso sugiro o AntiSamy que funciona que é uma beleza e permite configurar como a “limpeza” vai ser feita. Bem fácil.

https://www.owasp.org/index.php/Category:OWASP_AntiSamy_Project

Valeu galera!

Boa Tarde,

Alias, como vc implementou esse Wrapper? Vc sanitiza parâmetro por parâmetro do request ou vc sanitiza o request inteiro? em um request com muitos atributos fica malzão pegar atributo por atributo,quase inviável como tava vendo em alguns exemplos com o JSoup, um exemplo mais pratico seria dar escape nos inputs de entrada como descrito em
http://stackoverflow.com/questions/2658922/xss-prevention-in-java
Lucas o Vraptor não tem nenhum filtro ou componente especial que trate disso? se não seria uma boa implementação para o futuro,mais uma pergunta,como fazer pra protejer meu código fonte? tem alguma forma de criptografar ou protejer para que meu código não possa ser alterdo por ferramentas como o firebug por exemplo???

Tipo se eu tiver um input hidden com um id ou valor de uma compra por exemplo isso pode ser facilmente alterado por ferramentas como o firebug,como evitar que isso aconteça?

[quote=rjpereira1000000]Boa Tarde,

Alias, como vc implementou esse Wrapper? Vc sanitiza parâmetro por parâmetro do request ou vc sanitiza o request inteiro? em um request com muitos atributos fica malzão pegar atributo por atributo,quase inviável como tava vendo em alguns exemplos com o JSoup, um exemplo mais pratico seria dar escape nos inputs de entrada como descrito em
http://stackoverflow.com/questions/2658922/xss-prevention-in-java
[/quote]

Entao, no meu request wrapper eu trato atributo por atributo sim. Sobrescrevi o metodo “getParameter” e devolvo o valor limpo pra quem requisitou. Inclui um cachezinho dentro dessa classe pra nao ter que limpar o mesmo parametro mais de uma vez, então não teve nenhum efeito degradante na performance.

cara, é meio difícil se proteger de alterações no html…

o que vc pode fazer é do lado do servidor verificar se o usuário tem permissão de alterar o dado do id foi passado…

outra coisa que vc pode fazer pra dificultar é não usar id numérico sequencial, use algo maior tipo UUID.

Uma outra alternativa para não expor os dados em campos hidden seria como já até me indicaram usar a sesão,mas sei lá tenho medo,se eu ficar usando a sessão para passar dados entre as páginas não poderia prejudicar a escalabilidade e aumentar o consumo de memória,mesmo colocando apenas tipos simples como inteiros?