Protegendo sua aplicação – Mini Livro

Um bom hacker sempre tem tempo

Certa vez enquanto eu participava de um curso sobre segurança ouvi a seguinte afirmação do especialista: “até mesmo a menor variação no número de bytes retornado na resposta de um request feito ao servidor será analisado por um hacker”. Um bom hacker terá a paciência de escovar os bytes retornados, HTTP Headers, campos escondidos e qualquer outra informação que possa ser válida.

Analisando a afirmação acima é possível pensar no seguinte: “o que nossos projetos têm retornado aos usuários?” ou “quando uma RuntimeException acontece, qual a resposta é enviada ao usuário?”. Quando eu falo de resposta ao usuário eu não digo apenas o texto exibido, mas digo também sobre headers, campos escondidos, etc.

É preciso estar atento a esses detalhes, pois um bom hacker vai gastar seu tempo investigando cada detalhe do seu projeto. Supondo um projeto onde apenas a tela de login seja possível acessar sem um usuário e ou senha válida, veja algumas coisas que um hacker poderia analisar ou tentar (veremos mais a frente):

  • SQL Injection
  • XSS
  • Bytes recebidos
  • Variação das mensagens recebidas
  • Brute Force Attack
  • Campos escondido

Note que apenas com uma página diversos tipos de ataques e análises de dados podem acontecer.

Cuidado com a informação retornada

É preciso sempre analisar a informação que é retornada ao usuário. No começo da internet era muito comum encontrar a seguinte mensagem ao errar o usuário na hora do login: “usuário incorreto”; a mensagem vista poderia levar um hacker a tentar alterar o usuário até certar um, que seria quando a seguinte mensagem apareceria: “senha incorreta”. O problema agora é que um hacker já conseguiu ter um login válido ao nosso projeto, bastaria tentar diversas senhas até conseguir uma válida.

O problema visto acima seria facilmente resolvido com a mensagem: “usuário e/ou senha inválidos”. Note que não foi preciso aumentar a proteção do código ou até mesmo criar diversas regras de segurança. Um hacker nunca saberia se ele conseguiu ou não um login válido por causa da mensagem acima.

Outro problema de mensagem retornada seria que, ao excluir um usuário, exibir um texto como: “Você não tem permissão para excluir um registro. Apenas usuário com o papel de ADMIN pode excluir”. É necessário mesmo que um usuário fique sabendo que existe o papel de ADMIN? Por que expor o modelo de negócio do projeto sem necessidade? Você poderia ter uma mensagem como: “Você não tem permissão para excluir” ou até mesmo “Não foi possível excluir o registro agora, caso o erro persista, entre em contato por email e informe o código 3345981UAI”. A vantagem da segunda opção é que você vai ter idéia de qual usuário está tentando fazer alguma ação ilegal, pois ele virá até você.

Um exemplo que encontrei recentemente foi do jogo Candy Crush. Uma amiga ao jogar encontrou a seguinte mensagem de erro:

candy01_edited

Veja que foi exibido a URL que o aplicativo utiliza para fazer a conexão com o servidor. Era necessário mesmo? Por que um usuário precisa ver essa mensagem tão técnica? O que uma pessoa que entende alguma coisa de programação poderia fazer com essa mensagem? Ele poderia simplesmente disparar diversas chamadas e encontrar falhas de segurança.

Por curiosidade eu chamei a URL no browser e olha o que foi retornado:

candy02_edited

Qual a necessidade disso? Expor todos os métodos da classe? Se quando eu chamei a URL sem parâmetros toda essa informação me foi passada, o que aconteceria seu eu começasse a passar parâmetros na URL?

Um bobeira de uma mensagem de erro não tratado pode causar graves problemas ao seu projeto.

Cuidado com o tamanho da mensagem retornada

É preciso ter cuidado com o tamanho da mensagem retornada ao usuário. Imagine que toda vez que algum erro aconteça, o usuário será levada a uma tela que exista apenas o texto: “desculpe, aconteceu um comportamento inesperado”. Independente do erro o usuário sempre irá para a mesma tela com a mesma mensagem, ou algo bem próximo variando apenas uma pequena porção do texto.

Apesar da solução de tela com uma mensagem ser uma ótima solução, um bom hacker analisará a quantidade de bytes retornados em cada resposta; com essa informação em mão ele poderá realizar diversos tipos de erros e testes para descobrir o que pode estar variando nos bytes retornados, em que caso ele poderia causar dados corrompidos no projeto ou até mesmo se ele conseguiria derrubar o projeto provocando erros.

Um modo para tratar a mensagem retornada é sempre ter uma tela/campo padrão variando apenas o texto exibido, validar se os headers enviados são sempre os mesmos e sem nenhuma informação desnecessária.

Firewall/SSL não faz mágica

Existem pessoas que pensam que com um bom firewall e utilizando SSL (HTTPS na URL) já estão com seus problemas resolvidos, afirmar isso é um erro enorme.

Firewall configurado corretamente pode impedir hackers de invadirem a rede, navegar no servidor, etc. Ao utilizar SSL (HTTPS) podemos evitar o ataque do tipo Man in the Midle (veremos na próxima página).

São duas ferramentas muito boas pare evitar determinados tipos de ataque, mas existem diversos outros tipo que facilmente passariam por essas defesas: Injection (SQL, XPATH, LADP), XSS, dados incorretos enviados, falha em regras de negócio por código não corretamente programado, etc.

Tome cuidado ao achar que a responsabilidade proteção do projeto deve ficar apenas na Infra. Creio que toda a equipe do projeto deveria ser envolvida quando o assunto é segurança.

31 thoughts on “Protegendo sua aplicação – Mini Livro

  1. Achei muito positiva a iniciativa… acompanho o blog sempre que posso como maneira de estudo e sempre achei que isto é algo que falta na visão dos desenvolvedores e/ou analistas, porque impactam em outras áreas e medidas pequenas ajudam no que circunda uma aplicação.

    • Henrique, boa tarde.

      Realmente é difícil ver o assunto segurança em blogs ou foruns.

      Ultimamente li muito material sobre segurança e resolvi compartilhar. [=

      Obrigado pelo apoio! =D

  2. Parabéns pela iniciativa, Hebert!! Sempre tenho visto os posts e são sempre sobre um tema atual, interessante e este, um tema que pouco se ver falar. Vou terminar de ler, mas me parece bem interessante. Mais uma vez, parabéns!

  3. Parabéns por mais este excelente post!!!
    Mas eu gostaria de saber,e tenho certeza que outras pessoas que acompanham seu site também é quando teremos um livro da casa do codigo – EJB 3.2 Eficaz? rsss, já tenho a JSF Eficaz, JPA Eficaz.

    • Jivago, boa tarde.

      Muito obrigado pelo apoio, fico feliz por saber que estou ajudando.

      Quanto ao livro infelizmente não depende só de mim, mas do pessoal da casa do código também. [=

      Até mais.

  4. Parabéns Hebert :D os seus conteúdos são muito top :D

    E eu feliz aqui com meus 11k acessos do meu blog hauahuahua
    mas não crio nada, apenas posto soluções de exceptions/erros
    e tradução de alguns artigos que acho útil :D

    é isso ai… continue com o ótimo trabalho :D

    Abraços!

    • Gustavo, boa tarde.

      Obrigado pelo apoio.

      Eu vejo qualquer ajuda importante.

      Eu também fiquei feliz da vida quando fiz 10k de visitas algum tempo atrás.

      O importante é não desanimar. [=

      Até mais.

    • Jeferson, boa tarde.

      Obrigado pela visita, e desculpe a demora em responder. Estive muito ocupado nesse último mes.

  5. Parabéns pelo excelente post hebert, esse trabalho que você faz aqui no blog de compartilhar conhecimento é fantástico!

  6. Fiz um teste utilizando XSS, salvei como Teste
    E não funcionou =/

    Aqui não teve como por o link direito, mas eu fiz um link e não funcionou =I

    • Marcos, boa tarde.

      Nesse caso você não colocou a URL, por isso não apareceu direito. Acredite ou não, aqui para mim o Teste está parecendo diferente. [=

      Obrigado pela visita.

      • Boa Noite Hebert ,
        Aqui no blog ficou como link, mais na minha aplicação não ocorreu isso , ficou normal e até um script não rodou.
        Mas eu confio no que você diz e me atentarei com isso nas próximas vezes.

        Sensacional esse mini-livro, já li todos os livros e mini-livros seus[ tenho eles impressos para auto-ajuda].

        Impossível destacar qual o melhor, são todos sensacionais!

        Sou teu fã de carteirinha assinada tenho todas as coleções dos mini-livros e dos EFICAZES ( Jpa e JSF ), estou muito ansioso para o próximo lançamento do EFICAZ!.
        Deus continue te dando sabedoria, peço isso diariamente.
        Quero ser igual a você, com todo esse conhecimento algum dia, meu ídolo!

        Abraços, meus parabéns e até a próxima !

  7. Execelente mini livro, através dele estou podendo adquirir uma bela noção de segurança em aplicações que,particularmente, é uma área que me fascina e que é de suma importância, pois ataques especializados estão se tornando cada vez mais frequentes.

    Baixando o PDF para consulta posterior, mas voltarei a visitar esse site mais vezes!

  8. Não costumo comentar em blogs, mas nesse caso é preciso.
    Parabéns pelo trabalho cara, obrigado por compartilhar o seu conhecimento com a comunidade!

  9. Inacreditável pois quando aprendemos e lemos sobre o assunto de brechas de segurança e erros de programação, a primeira imagem que vem em mente é um estagiário criando seus primeiros códigos ou um estudante aprendendo sobre alguma linguagem e que saiu vendendo seus sites/projetos sem ter o conhecimento mínimo necessário, mas então vemos exemplos de erros e brechas da Microsoft, NASA, Yahoo, Nasdaq, governos entre tantos outros, é no mínimo cômico :D . Gostei muito deste seu mini livro, tem uma visão macro de muitos detalhes imprescindíveis para a sólida construção de um software. Parábens!

  10. Olá. Parabéns pelo blog. São ótimos os tópicos: atuais e revelantes. Já adicionei ao meu leitor de feeds.

    Fiquei com uma dúvida ao ler seu mini-livro e gostaria de ouvir sua opinião. E quanto ao uso de senhas e usernames em arquivos XML, como o persistente.xml do JPA? O que você recomenda? Criptografar o arquivo? E quanto à colocar senhas no próprio código fonte?

    Obrigado. Paulo.

    • Paulo, boa noite.

      Primeiro, me perde a demora em responder. Estou muito pegado no trabalho, para você ter idéia, estou te respondendo dele enquanto um deploy não termina.

      Honestamente não recomendo colocar senha nem no persistence.xml e nem no código. Para mim o melhor local para se colocar a senha é na configuração de pool de conexão que pode ficar dentro do servidor. Ao configurar o pool de conexão (ex.: tomcat, jboss, etc) você pode colocar a senha criptografada. A vantagem dessa abordagem é que você não precisará fazer um novo deploy da aplicação apenas por uma senha trocada.

      Espero ter ajudado, obrigado pela visita e pelo apoio.

  11. Outra dúvida: e quanto ao uso do atributo “rendered” do JSF para esconder informações importantes? Por exemplo, quando alguém esconde de um usuário comum, alguns itens de menu que só devem ser vistos por um usuário cadastrado no sistema.

    • Paulo, boa noite.

      Eu recomendo sempre esconder, mas ainda assim bloquear o acesso no código. Eu penso que se o usuário não deve ter acesso a informação, ela não deve nem ser enviada a tela.

      Espero ter ajudado. Obrigado pela visita.

      • Aí reside a minha dúvida: quando uso o “rendered”, os dados que não devem ser vistos são enviados na resposta da requisição e os mesmos são escondidos no browser do usuário (via JS, por exemplo)? Ou o JSF detecta, no lado do servidor, que os dados não devem ser enviados, altera a árvore de componentes e envia a resposta já omitindo esses dados? Obrigado.

        • Paulo, boa noite.

          Vou te dar uma resposta que você não esperava ouvir: “Por que você não faz o teste e coloca a resposta aqui? Esse teste é fácil de reproduzir. Após a página ser exibida, olhe o código fonte. Coloque em seu código códigos como System.out.println(“passou aqui”) para você saber por onde sua chamada passou”.

          Obrigado pela visita.

Leave a Comment