Alura > Cursos de Programação > Cursos de Java > Conteúdos de Java > Primeiras aulas do curso Segurança web em Java parte 2: XSS, Mass Assignment e Uploads de arquivos!

Segurança web em Java parte 2: XSS, Mass Assignment e Uploads de arquivos!

Cross Site Scripting (XSS) - Introdução

Olá, pessoal, tudo bem? Eu sou o Rafa Nercessian e eu vou dar uma introdução sobre a o que nós vamos estar vendo nessa segunda parte desse curso de segurança, utilizando aqui o Spring MVC.

Nessa segunda parte, nós vamos ver essa aba de depoimentos onde o usuário supostamente iria colocar essa mensagem sobre como foi a experiência dele em comprar os ingressos na Alura Shows e tudo, mas nós vamos ver que um desses usuários não vai fazer exatamente isso que nós imaginamos, de colocar uma mensagem e, sim vai colocar um código aqui pra tentar comprometer o sistema da Alura Shows.

Nós vamos verificar como é que nós podemos validar essas entradas que esses usuários podem colocar nesses campus aqui de título e do depoimento. Depois, nós vamos ver aqui um caso bastante interessante, que quando o usuário faz um registro nessa nossa aplicação da Alura Shows ele deveria só ter acesso a parte da aplicação referente ao que o usuário comum que foi registrado tem acesso.

Que seria pra visualizar o perfil, eventualmente ver os shows, ver o preço dos ingressos. Ele não deve acessar a parte administrativa. Tem diferentes perfis de usuários aqui nesse nosso sistema, ou seja, o usuário que vem aqui na aplicação e se cadastra na Alura Shows, ele não deve, por exemplo, acessar o painel administrativo, a área administrativa da Alura Shows.

Mas nós vamos ver, que vão acontecer alguns casos bastante interessantes que um usuário dessa nossa aplicação vai se cadastrar e vai conseguir manipular o atributo da nossa classe para poder se transformar no usuário administrador e entrar na parte administrativa da Alura Shows. Nós vamos ver como é que nós conseguimos proteger essa nossa aplicação contra esse tipo de tentativa.

Depois, para finalizar nós verificamos aqui que na hora de um usuário fazer um registro nessa aplicação da Alura Shows, ele tem que colocar o nome, o e-mail e a senha. E tem essa parte da imagem, que é um arquivo. E será que aqui a Alura Shows tinha feito inicialmente a verificação de qual arquivo pode ser esse? Nós vamos testar isso. Nós vamos colocar alguns arquivos diferentes de uma imagem e vamos ver o que pode acontecer nessa nossa aplicação.

Então, essa é a segunda parte do curso, é importante que vocês tenham feito a primeira parte porque nós vamos seguir com o mesmo projeto. Então nós já corrigimos alguns pontos na primeira parte. Se você ainda não viu, dá olhada na primeira parte. E nos encontramos para seguir esse projeto da Alura Shows. Eu aguardo vocês, sejam muito bem-vindos e eu espero que o curso ajude no crescimento profissional de vocês. Até mais.

Cross Site Scripting (XSS) - Cross Site Scripting (XSS)

Nós compramos os ingressos aqui da Alura Shows e agora nós queremos deixar um depoimento pra Alura Shows para que todos os usuários saibam que a nossa experiência foi muito boa, que nós conseguimos bons ingressos e que ficamos bastante contentes.

Então nessa aba depoimentos nós vamos querer deixar esse depoimento para a Alura Shows e para os demais usuários que forem visualizar, que forem acessar a Alura Shows saberem como é que está sendo a experiência dos usuários com as compras.

Vamos colocar o título da nossa mensagem de depoimento como sendo "ingressos ótimos", e falamos: "gostei bastante dos preços dos ingressos, eram acessíveis e com ótimos lugares". E clicamos no botão para enviar esse nosso depoimento. Clicamos aqui "enviar". Agora, vamos tentar entender o que acontece por debaixo dos panos para que nós tenhamos essa nossa postagem aparecendo aqui nessa nossa JSP.

Eu tenho aqui essa apresentação que eu acho que vai ficar um pouco mais fácil pra entendermos. Então, eu tenho aqui esse meu computador que é esse computador da gravação, acabamos de rodar esse teste do depoimento. E o que nós estamos fazendo?

Quando clicamos no botão de "enviar". Nós estamos fazendo o que? Uma requisição para o nosso Tomcat, para o nosso servidor aqui. Vai ter uma parte do Tomcat, algum método que vai estar cadastrando, persistindo esses dados do depoimento no banco de dados. Nós também temos que ter um método para pegar essas mensagens, esses depoimentos do banco de dados e voltar, aqui no caso, para o usuário.

Então, é esse fluxo que tá acontecendo. Se formos aqui na nossa aplicação, vamos clicar com o botão direito do mouse, no botão enviar e inspecionar, e quando nós clicamos no botão "enviar", a nossa mensagem de depoimento está sendo encaminhada aqui pra esse endereço "envia mensagem".

Nós temos que ter lá um método no nosso pacote Controller que está respondendo a essa requisição para esse endereço "envia a mensagem". Vamos conferir? Vamos aqui na nossa aplicação no eclipse. E aqui no nosso pacote de Controller, nós temos essa classe depoimento Controller. Vamos clicar nela?

Depoimento Controller. E aqui nós temos o nosso endereço "enviar mensagem" e o que tem dentro desse método aqui que está tratando essa requisição para esse endereço "enviar mensagem", nós estamos salvando o depoimento no banco de dados e temos aqui um método chama posts do banco.

Nós estamos chamando essas mensagens que foram cadastradas aqui no banco de dados. Então, com isso o que acontece? Se nós formos lá, no caso do nosso usuário Alex, que que nós estamos utilizando-o para fazer essas simulações de ataques na nossa aplicação, o que ele pode pensar? Bom, ele vai voltar para o computador dele, do Kali Linux e ele vai querer visualizar essa parte de depoimentos também para ver o que os usuários da Alura Show estão dizendo.

Vou só logar aqui no Kali Linux e aqui nós colocamos o endereço de acesso da nossa aplicação, deixa só eu colocar aqui, Alura Shows, e nós temos aqui a parte de depoimentos, como nós vimos, a mensagem que eu escrevi no meu computador do Windows, que é um outro computador, ela apareceu aqui no Kali Linux do Alex.

O que o Alex pensa? Ele pensa “será que os desenvolvedores da Alura Shows chegaram a fazer uma espécie de filtro, alguma checagem dessas informações que podem ser passadas aqui no título e na mensagem?”. Porque se eles não fizeram, o que o Alex vai tentar realizar? Bom, vamos voltar aqui para apresentação para entender o que o Alex vai poder conseguir se os desenvolvedores da Alura Shows não tenham feito uma análise do que o usuário pode passar nesse campo de título e mensagem.

Bom, nós sabemos que o nosso browser interpreta código JavaScript. Então, o nosso hacker, o Alex, ao invés de colocar uma mensagem dizendo como é que foi a experiência dele com sites da Alura Shows, ele vai tentar colocar nesse campo um código JavaScript e, como nós vimos, o que vai acontecer?

Quando ele clica no botão de enviar, essa informação seria passada para o nosso servidores do Tomcat, para a nossa aplicação e nós temos o método enviar mensagem que está certo, que tá persistindo esse depoimento no banco de dados e nós temos aquele método chama posts do banco, que está pegando todas essas mensagens do banco de dados. Agora, o que acontece se uma dessas mensagens aqui for um código Javascript?

Se é um código JavaScript, essa mensagem seria devolvida aqui pro nosso usuário, porque as mensagens estão sendo carregadas na página. E uma dessas mensagens é um código JavaScript. E o que o Alex vai conseguir fazer com isso? Se qualquer usuário que for acessar agora essa parte do depoimento, outro usuário, por exemplo, do meu computador do Windows, caso acesse a página de depoimento e caso uma dessas mensagens que foram cadastradas no banco de dados foi de um código JavaScript, esse código JavaScript vai parar no browser desse outro usuário também.

E com isso nós temos um ataque conhecido aqui como cross-site-scripting, que é justamente onde nós inserimos códigos JavaScript podendo comprometer a segurança de outros usuários. Então, vamos tentar fazer essa simulação aqui do Alex?

O Alex é um ativista do grupo do Anonymous e quer testar, verificar se a aplicação da Alura Shows apresenta essa vulnerabilidade. Então ele vai querer colocar uma imagem do grupo do Anonymous, para que todo mundo saiba que o grupo do Anonymous que descobriu essa vulnerabilidade na Alura Shows.

Vamos voltar no computador do Alex, aqui no Kali Linux, e o Alex vai tentar fazer esse teste com a aplicação da Alura Shows para ver se por um acaso os desenvolvedores esqueceram de validar o que os usuários pode estar passando nesses campos aqui. Então, vamos colocar o título "gostei bastante", até aqui tudo bem, e agora na mensagem, o Alex vai colocar esse código JavaScript.

Como é que você insere um código JavaScript? Nós temos que abrir a tag, e colocar "script" e fechamos a tag. Aqui dentro dessa tag script, nós vamos configurar essa imagem do grupo Anonymous. Então, o primeiro passo, o que eu quero fazer? Deixar todo esse documento da parte de depoimentos com um fundo branco para que eu coloque a imagem em cima.

Eu vou colocar aqui “document.body.innerHTML=””.Uma vez que nós já colocamos esse código, a nossa tela do depoimentos ficaria em branco, e o que nós vamos fazer? Nós queremos colocar essa imagem do Anonymous aqui no lugar da parte dos depoimentos.

Vamos criar esse objeto imagem. Colocamos “var imagem=new.image():” E agora nós queremos vincular o endereço dessa imagem com uma imagem do Anonymous. Então, eu estava pesquisando umas imagens do Anonymous e encontrei essa imagem aqui para usarmos como base. Eu vou só copiar aqui.

Vou copiar o local da imagem e nós vamos colocar imagem.src =”, a origem da imagem está onde? Está nesse endereço aqui que do Pixabay, é a imagem do Pixabay saber que eu estou usando. Então está aqui. E agora o que nós queremos fazer? Nós queremos juntar esse objeto imagem no corpo do nosso depoimento JSP, no corpo dessa nossa página.

Então, para isso nós temos que vir aqui e colocar “document.body.”, e nós queremos fazer o quê? Nós queremos fazer essa junção desse objeto imagem no body. Nós chamamos aqui “appendChild(imagem).”.

Com isso se nós já terminamos a nossa configuração nós pode fechar a tag scrip. Isso quer dizer aqui, que caso os desenvolvedores da Alura Shows não tenham feito nenhuma espécie de filtro do que o usuário pode estar passando nesses campos, o que vai acontecer? Esse código JavaScript vai para o nosso banco de dados e temos o nosso método que chama todas essas mensagens do banco de dados.

Agora, se uma dessas mensagens for um código JavaScript, esse código JavaScript é interpretado pelo browser e todos os usuários vão estar visualizando essa imagem do grupo do Anonymous. Então, vou verificar se o Alex vai ter sucesso nessa tentativa de ataque dele. E se por um acaso os desenvolvedores da Alura Show esqueceram de fazer essa verificação, vamos lá. Vou clicar em e enviar.

Olha aqui, pra mim já apareceu. Para mim aqui no computador do Kali Linux já apareceu a imagem do Anonymous. Então, isso nos leva a crer que de fato os desenvolvedores da Alura Shows se esqueceram de validar o que o usuário pode estar passando como parâmetro nesses campos. Agora vamos fazer o seguinte só para confirmar, vamos sair aqui do Kali Linux e vamos voltar para o nosso computador do Windows, que é um outro usuário, outro computador e vamos clicar na aba depoimentos e vamos ver se vamos a imagem do grupo do Anonymous.

Vamos lá. Depoimentos e está aqui a imagem do grupo do Anonymous. O Alex conseguiu, de fato, ter sucesso nesse ataque de cross-site-scripting que ele acabou de realizar. Agora nós temos que justamente encontrar uma forma de evitar que esse ataque aqui aconteça. Vamos ver na próxima etapa.

Cross Site Scripting (XSS) - Trabalhando com validações

A aplicação da Alura Shows não estava dando o que o usuário pode estar passando no campo do título e da mensagem do depoimento e, com isso, o Alex conseguiu inserir um código JavaScript para mostrar essa imagem do grupo do Anonymous. Então, nós precisamos verificar que informações o usuário pode estar passando no campo de título e de mensagem, com o objetivo de evitar esse ataque aqui de cross-site-scripting.

Para isso nós vamos utilizar a interface validator que o próprio Spring oferece para nós. Então, vamos voltar no nosso projeto aqui e nós temos que criar essa nova classe para fazer a implementação dessa interface validator.

Nós colocamos “Ctrl + N” e colocamos e que vamos criar essa nova classe e nós vamos guardar essa nova classe em um pacote de validação, que vamos chamar de validator. E o nome dessa nossa classe que vamos criar vai ser a depoimento validator. Nós voltamos aqui e implementamos essa interface validator aqui do Spring.

E quando nós fazemos essa implementação dessa interface validator, nós somos obrigados a implementar esses dois métodos. O método suports e o método validate. Esse método suports recebe como argumento a classe do objeto que nós estamos querendo validar e vai indicar para nós se essa nossa classe depoimento validator que nós estamos criando, se ela consegue de fato validar os objetos dessa classe que serão recebidas como argumento.

Então, vou só mudar o nome desse argumento, desse parâmetro, pra ser mais semântico. E o que nós queremos verificar? Nós queremos verificar se essa classe aqui passada como argumento é equivalente à classe depoimento, porque assim nós teríamos um retorno true e conseguimos seguir para a validação do objeto.

Nós queremos verificar se essa classe que foi recebida como argumento é equivalente a classe depoimento. Então, nós chamamos aqui “depoimento.class” e nós queremos verificar esse grau de equivalência, nós queremos verificar se elas são assinaláveis. Nós chamamos o método aqui “isAssignableFrom(clazz)”.

Com isso o que eu estou fazendo? Eu estou verificando se essa classe recebida como argumento nesse nosso método suports, é equivalente a essa nossa classe depoimento. Se elas forem equivalentes, tem o que? Tem um retorno true e nós conseguimos ter nesse método validate a validação do objeto em si.

Nós temos o quê nesse método validate? Nós temos esses dois parâmetros, o parâmetro object, que de fato é o objeto que estamos querendo validar e temos esse outro parâmetro que é o parâmetro de erros que nós vamos estar guardando esses nossos erros de validação. Então vamos também trocar os nomes para ficar mais semântico.

Aqui vamos colocar target e aqui colocamos errors. Eu preciso fazer a validação do que o usuário está passando no campo do título e da mensagem. Então, o Alex aqui pra ele ter sucesso nesse ataque dele, o que ele teve que fazer? Ele teve que abrir uma tag, colocar o nome script e fechar a tag. Então, a nossa estratégia para evitar esse ataque de cross-site-scripting é justamente o quê?

Verificar se no campo do título e da mensagem tem alguma abertura ou fechamento de tags. Se tiver alguma abertura ou fechamento de tags, nós vamos falar pro usuário: "olha, usuário você está colocando alguma mensagem aqui meio estranha, então, nós não vamos aceitar". Essa é a validação que nós vamos fazer com o objetivo de evitar esse ataque de cross-site scripting. Esse nosso objeto target aqui nós temos que fazer um casting para dizer que esse objeto é do tipo depoimento.

Nós vamos aqui e dizemos que esse nosso target, na verdade, é um objeto do tipo depoimento. Agora que eu já tenho esse objeto depoimento porque já fizemos a validação da classe, nós conseguimos fazer a validação desse objeto depoimento aqui. Nós temos que pegar desse objeto depoimento o título, o campo do título e da mensagem para verificarmos se contém a abertura e fechamento de tags.

Nós vamos aqui e chamamos o gater. Colocamos “depoimento,getTitulo();” “Ctrl + 1” e assinalamos uma variável local, que chamamos de título e também chama o gater da mensagem “mensagem = depoimento.getMensagem();” “Ctrl + 1” e assinalamos o nome dessa nossa variável como sendo mensagem.

Então, o que nós queremos é verificar? Se o campo do título aqui conter abertura, ou se ele contiver fechamento de tags, o que nós queremos fazer? Nós queremos rejeitar esse valor, então, nós chamamos esse nosso objeto do tipo erros para chamar esse método, indicando que vamos rejeitar esse valor, “erros.rejectValue(arg0, arg1);” e nós temos gente dois parâmetros reject value.

O primeiro parâmetro é o atributo que nós temos na nossa classe depoimento que nós estamos querendo validar que, no caso, é quem? É o nosso título aqui. Então, nós colocamos o nome do atributo que está na nossa classe que também é título e aqui esse segundo parâmetro é a chave de identificação desse erro para que o Spring consiga encontrar depois uma mensagem personalizada para mandar para o nosso usuário.

Nós ainda não temos essa mensagem, mas já vamos criar esse código de erro pra que o Spring depois consiga localizar. Nós vamos colocar esse código de erro, poderia ser, em tese qualquer nome, mas vamos colocar aqui, por exemplo, “erros.titulo”. Caso nós tenhamos aqui a abertura ou fechamento de tags no campo do título, nós estamos rejeitando esse valor. Nós temos que fazer essa mesma validação para a mensagem.

Então, se a mensagem contiver a abertura ou fechamento de tags nós também vamos rejeitar esse valor e vamos falar pro usuário que a mensagem dele aqui não é válida. Nós chamamos nosso objeto “erros.rejectValue”. E passamos o primeiro parâmetro, que é o atributo, que temos na nossa classe depoimento, que é “mensagem” e aqui colocamos o código de erro que vamos estar passando para o nosso usuário. Colocamos “erros.mensagem”, depois nós vamos ter que criar uma mensagem personalizada com essa chave aqui que nós acabamos de colocar.

Com isso nós criamos essa nossa classe depoimento validator. Nós temos que utilizá-la no nosso controller depoimento. Vamos colocar aqui “Ctrl + Shif + R” para localizarmos a classe depoimento Controller. Nós queremos que, quando esses parâmetros forem enviados do formulário, na criação desse objeto, seja feita essa validação. Então, nós temos que usar a notação valid da especificação bin validation.

Aqui no nosso método enviar mensagem, quando esse nosso objeto depoimento for criado, nós queremos fazer a validação dele. Então, colocamos aqui “@Valid”. Coloca aqui “Ctrl + Shift + O” para fazer a importação certa. E agora como é que o Spring vai saber que nós estamos querendo fazer a validação de fato com a configuração que nós fizemos aqui nessa classe depoimento validator?

Nós temos que especificar isso pro Spring. Nós fazemos essa especificação através da notação InitBinder. Vamos colocar aqui essa notação InitBinder pra justamente nós podermos chamar essa classe depoimento validator para que esse nosso objeto depoimento que foi criado seja validado de acordo lá com o depoimento validator, a classe que nós acabamos de criar com as configurações de validação que precisamos.

Aqui nós vamos ter o nosso método, public. Vamos colocar aqui void, o retorno dele, e o nome InitBinder e ele vai receber como argumento o objeto do tipo aqui WebDataBinder. Nós vamos colocar esse Binder justamente pra citar esse validador. Então, colocamos setvalidator e vamos colocar mil. Colocamos aqui que queremos fazer essa validação baseada no que foi especificado na classe depoimento validator.

Vamos só recapitular o que nós fizemos aqui. Nós criamos essa nossa classe depoimento validator. Essa classe depoimento validator implementa essa interface validator do Spring e nós somos obrigados a sobrescrever esses dois métodos. O método suports recebe como argumento aqui a classe do objeto que estamos querendo validar e retorna, se essa nossa classe depoimento consegue lidar com a validação dos objetos que são recebidos aqui como argumento dessa classe.

Caso a classe que recebermos como argumento for equivalente a classe depoimento.class aqui, nós temos o que? O retorno true e conseguimos fazer a validação do objeto. Esse nosso objeto vai ser um objeto do tipo depoimento, nesse objeto depoimento nós queremos fazer a validação do campo do título e da mensagem, para verificar se tem aberturas ou fechamento de tags, se tiver abertura ou fechamento de tags nós vamos rejeitar esse valor, porque o Alex não vai conseguir colocar mais aquela tag script para poder inserir aquele código JavaScript.

E uma vez que nós criamos essa classe depoimento validator, nós temos o que? Temos que voltar no nosso controller e especificar que, quando esse nosso objeto depoimento for criado com as informações vindas do formulário nós vamos validar essas informações e nós utilizamos essa notação InitBinder pra especificar para o Spring que nós estamos setando o nosso validator aqui, a validação que tem que ser feita, que tem que ser com base nessa nossa classe depoimento validator, porque nós especificamos a abertura ou fechamento de tags.

Agora falta só nós configurarmos depois a mensagem personalizada, porque nós ainda não fizemos isso, nós só colocamos esses nossos códigos errors título e errors mensagem, mas nós ainda não criamos nada com relação a essas chaves, não fizemos ainda essa mensagem personalizada. Vamos fazer na próxima etapa para depois mostrar essas mensagens para o usuário.

Sobre o curso Segurança web em Java parte 2: XSS, Mass Assignment e Uploads de arquivos!

O curso Segurança web em Java parte 2: XSS, Mass Assignment e Uploads de arquivos! possui 96 minutos de vídeos, em um total de 38 atividades. Gostou? Conheça nossos outros cursos de Java em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Java acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas