image

Bootcamps ilimitados + curso de inglês para sempre

80
%OFF
Article image
Guilherme Silva
Guilherme Silva27/02/2025 17:50
Compartilhe
Microsoft Certification Challenge #3 DP-100Recomendados para vocêMicrosoft Certification Challenge #3 DP-100

Segurança no Desenvolvimento Web com Java

    Apesar dos constantes avanços na segurança digital, o conceito de que "nenhuma segurança é perfeita e nunca será" continua a se provar verdadeiro. Exemplos recentes, como um caso envolvendo o Banco Neon e a falha de segurança CVE-2025-21298, no qual, o próprio invasor do Banco Neon destacou que a brecha explorada era relativamente simples e a nível nacional, demonstrando que mesmo sendo grandes empresas, não são imunes a vulnerabilidades. Em um caso específico da falha reportada na Microsoft, a correção foi disponibilizada rapidamente, mas isso não impediu que o incidente gerasse discussões acaloradas no LinkedIn e em diversas comunidades tech, reforçando a ideia de que até mesmo falhas básicas podem comprometer sistemas supostamente seguros.

    Mas é claro, isso não significa que você, Javeiro, pode simplesmente relaxar e esperar que as falhas de segurança apareçam nos seus SaaS ou até mesmo naqueles "projetinhos" que talvez nunca vejam a luz do dia, só porque viu que até mesmo as Big Techs enfrentam vulnerabilidades em seus sistemas. Segurança precisa ser levada a sério desde o início, porque quando as coisas dão errado, geralmente dão errado de verdade.

    Para evitar esse tipo de dor de cabeça, vou apresentar algumas boas práticas e bibliotecas – tanto nativas quanto externas – que podem ajudar a mitigar as principais vulnerabilidades nos sistemas atuais do mercado.

    1- Spring Security

    Quando falamos de Java e segurança, é impossível não lembrar de uma das melhores ferramentas disponíveis para esse propósito: Spring Security. Essa biblioteca é praticamente um padrão no desenvolvimento seguro de aplicações Java, oferecendo suporte robusto para autenticação, autorização, proteção contra ataques comuns e integração com diversos métodos de autenticação modernos, como OAuth2 e JWT.

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
      http
        .csrf(csrf -> csrf.disable()) // Desativa CSRF para testes (não recomendado em produção)
        .authorizeHttpRequests(auth -> auth
          .requestMatchers("/publico").permitAll() // Permite acesso sem autenticação
          .requestMatchers("/admin").hasRole("ADMIN") // Apenas ADMIN pode acessar
          .requestMatchers("/user").hasAnyRole("USER", "ADMIN") // USER e ADMIN podem acessar
          .anyRequest().authenticated()) // Qualquer outra requisição exige autenticação
        .formLogin(login -> login // Configuração do login padrão do Spring Security
          .defaultSuccessUrl("/user", true) // Redireciona após login bem-sucedido
          .permitAll())
        .logout(logout -> logout // Configuração do logout
          .logoutUrl("/logout")
          .logoutSuccessUrl("/publico")
          .permitAll());
      return http.build();
    }
    }
    

    Esse foi um exemplo relativamente básico (verboso) de configuração do Spring Security, utilizando alguns de seus principais métodos, como autenticação de roles (ADMIN e USER) em endpoints. Mas isso é apenas a ponta do iceberg dessa biblioteca.

    Se você quiser se aprofundar ainda mais, pode explorar JWT (JSON Web Token) e OAuth2, que permitem a criação de autenticação baseada em tokens, amplamente utilizada em aplicações modernas. No entanto, para realmente dominar essas tecnologias, é essencial entender conceitos como segurança da informação, criptografia e outros tópicos relacionados.

    E aqui vai uma recomendação de ouro: mesmo que pareça um clichê no nível daquele seu amigo ou familiar que "entende" de economia e insiste para você ler Pai Rico, Pai Pobre, eu recomendo fortemente que assistam ao vídeo do Fábio Akita: 📺 "Sua Segurança é uma DROGA | Gerenciadores de Senhas, 2FA, Encriptação"

    Esse vídeo traz insights valiosos sobre boas práticas de segurança digital e explica de forma direta por que a segurança da maioria das pessoas é fraca – e como melhorar isso de forma prática.

    2- Prepared Statement

    Chegamos a um tópico que não é útil apenas para aplicações web, mas para qualquer aplicação que interaja com um banco de dados: o PreparedStatement. Esse método faz parte da biblioteca nativa do Java, dentro do pacote

    java.sql
    

    Agora, você deve estar se perguntando:

    "Muito boa essa introdução sobre PreparedStatement, mas afinal, como ele funciona e o que ele impede???"

    Bom, o PreparedStatement simplesmente evita uma das vulnerabilidades mais caras do mundo do Bug Bounty, o temido SQL Injection.

    Para quem não está tão familiarizado com o termo, aqui está uma definição direta do site da Microsoft Learn sobre SQL Injection:

    "A injeção de SQL é um ataque em que o código mal-intencionado é inserido em cadeias de caracteres, passadas posteriormente para uma instância do mecanismo de banco de dados do SQL Server para análise e execução. Qualquer procedimento que construa instruções SQL deve ser verificado quanto a vulnerabilidades de injeção, porque o mecanismo de banco de dados executa todas as consultas sintaticamente válidas que recebe. Mesmo dados com parâmetros podem ser manipulados por um invasor qualificado e determinado."

    Ou seja, sem um controle adequado, um invasor pode modificar a estrutura da consulta SQL, acessando dados confidenciais, alterando informações ou até mesmo apagando tabelas inteiras.

    E é aí que o PreparedStatement entra para salvar o dia — e de forma muito sagaz, se quer saber minha opinião. Agora, vamos aos exemplos práticos: suponha que você tenha um sistema simples de cadastro de pinguins em um zoológico:

    String sql = "SELECT * FROM pinguins WHERE name = '" + name + "' AND password = '" + password + "'"; 
    Statement stmt = connection.createStatement(); 
    ResultSet rs = stmt.executeQuery(sql);
    

    E nosso atacante / user malicioso digite no campo de senha:

    ' OR '1'='1',
    

    E query gerada será:

    SELECT * FROM pinguins WHERE name = 'admin' AND password = '' OR '1'='1'
    

    como "1=1" sempre é verdadeiro, isso retornaria todos os pinguins(usuários), permitindo acesso indevido.

    Isso acontece pois o Statement simples, faz com que o Java concatene a string SQL com os valores do usuário permitindo que um atacante insira comandos maliciosos. Agora vamos observar o mesmo código só que com o PreparedStatement:

    String sql = "SELECT * FROM pinguins WHERE name = ? AND password = ?";
    PreparedStatement pstmt = connection.prepareStatement(sql); 
    pstmt.setString(1, name); 
    pstmt.setString(1, password); 
    ResultSet rs = pstmt.executeQuery(1);
    

     O que está acontecendo internamente?

    O SQL é enviado ao banco de dados primeiro, sem os valores do usuário O banco de dados pré-compila a consulta e separa a estrutura do SQL dos dados. Os valores são tratados como meros parâmetros e inseridos na consulta de forma segura. Agora, se um atacante tentar usar "username = admin e password = ' OR '1'='1", o banco de dados não interpretará isso como parte da lógica SQL. Em vez disso, ele tratará o input como um valor literal e buscará um usuário com senha exatamente igual a " ' OR '1'='1" — o que obviamente não existe (espero eu...).

    3- Bcrypt

    Ainda com o Spring Security, outro ponto muito importante quando falamos sobre segurança web são senhas, os jeitos de armazená-las e transportá-las do cliente ao servidor sem maiores problemas. E é aí que entra o BCRYPT, pois você não vai adicionar diretamente a senha ao banco de dados, de forma pura, quero dizer. Então, teremos que usar uma das features mais importantes, que é o "hashing seguro".

    E quando falamos de hashing de senhas em Java, um dos melhores métodos disponíveis é o Bcrypt. Ele é um algoritmo de hash forte e adaptável, utilizado para proteger credenciais de usuários de forma segura.

    Agora um exemplo de configuração básica:

    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    
    public class PasswordHashExample {
    public static void main(String[] args) {
      BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
      String senhaOriginal = "minhaSenhaSuperSecreta";
    
      // Gerando o hash
      String senhaHash = encoder.encode(senhaOriginal);
      System.out.println("Senha Hashed: " + senhaHash);
    
      // Verificando a senha
      boolean matches = encoder.matches("minhaSenhaSuperSecreta", senhaHash);
      System.out.println("Senha válida? " + matches);
    }
    }
    

    Um dos pontos que achei bem clever (inteligente) é a forma como esse algoritmo funciona e como ele se comporta em questões de desempenho. Sendo sincero, seu desempenho é devagar, mas você pode estar pensando:

    "Poxa, mas não é só otimizar utilizando outros algoritmos de hashing já vistos que funcionam em Log O(1)? 🤓☝️"

    Sim, mas essa demora não é por falta de conhecimento ou falta de vontade, e sim propositalmente desenhada para evitar uma possível invasão por BRUTE FORCE. O Bcrypt funciona devagar de propósito, dificultando qualquer tentativa de invasão.

    Conclusão

    Segurança não é só sobre usar bibliotecas, mas sobre compreender as vulnerabilidades e saber como mitigá-las da melhor forma possível. Desde a proteção contra SQL Injection, passando pela autenticação com Spring Security, até o hashing de senhas com Bcrypt, cada camada adicionada fortalece a segurança da sua aplicação.

    Agora que você tem uma base sólida, que tal continuar se aprofundando? Segurança é um dos tópicos mais valiosos para qualquer Javeiro que quer se destacar no mercado!

    Referências e Links Importantes

    Aqui estão algumas referências utilizadas e links importantes para aprofundamento:

    Compartilhe
    Recomendados para você
    Microsoft 50 Anos - Prompts Inteligentes
    Microsoft 50 Anos - GitHub Copilot
    Microsoft 50 Anos - Computação em Nuvem com Azure
    Comentários (1)
    DIO Community
    DIO Community - 28/02/2025 14:48

    Ótima abordagem, Guilherme! Segurança no desenvolvimento web é um tema crucial, e seu artigo traz uma visão clara e prática sobre como mitigar vulnerabilidades e fortalecer aplicações Java com Spring Security, Prepared Statements e Bcrypt.

    Na DIO, incentivamos que desenvolvedores vão além do básico e adotem boas práticas desde a concepção da aplicação. Sua explicação sobre SQL Injection, autenticação baseada em tokens e hashing de senhas reforça a importância de pensar na segurança como parte essencial do desenvolvimento, não como um complemento.

    Os exemplos que você trouxe demonstram como medidas simples podem evitar grandes problemas, garantindo proteção contra ataques comuns e reforçando a integridade dos dados. Para quem está construindo uma carreira sólida em Java e quer criar sistemas robustos e seguros, seu artigo é leitura obrigatória!

    Recomendados para vocêMicrosoft Certification Challenge #3 DP-100