Segurança de aplicações Kotlin: top-10 vulnerabilidades e métodos de proteção
Kotlin é uma das linguagens de programação que mais cresce, usada para desenvolvimento de aplicações Android, soluções server-side e projetos multiplataforma. Apesar dos mecanismos de segurança embutidos (null safety, imutabilidade de dados), os desenvolvedores frequentemente cometem erros que levam a vulnerabilidades graves. Neste artigo, analisaremos as top-10 vulnerabilidades de aplicações Kotlin e mostraremos como evitá-las.
1. Tratamento incorreto de tipos nullable (Null Safety)
Um dos pontos fortes do Kotlin é o sistema de tipos nullable. No entanto, os desenvolvedores frequentemente abusam do operador !! (not-null assertion), o que leva a NullPointerException em qualquer valor null inesperado.
Exemplo de vulnerabilidade:
fun getUserName(user: User?): String { return user!!.name // Se user = null, a aplicação quebra}Como corrigir:
fun getUserName(user: User?): String { return user?.name ?: "Convidado" // Chamada segura com valor padrão}Recomendação: Use ?.let, ?: (elvis) e safe casts. Evite !! em código de produção.
2. Injeção de SQL em aplicações server-side
Ao trabalhar com bancos de dados via JDBC ou Exposed, desenvolvedores às vezes concatenam strings de consulta, o que abre caminho para injeções de SQL.
Exemplo de vulnerabilidade:
val id = request.getParameter("id")val query = "SELECT * FROM users WHERE id = $id" // Concatenação perigosaComo corrigir:
val id = request.getParameter("id")val stmt = connection.prepareStatement("SELECT * FROM users WHERE id = ?")stmt.setString(1, id) // Usamos consulta parametrizadaRecomendação: Sempre use PreparedStatement ou bibliotecas ORM (Exposed, Hibernate) com parametrização.
3. Armazenamento inseguro de dados (SharedPreferences)
Em aplicações Android, frequentemente armazenam tokens, senhas e outras informações confidenciais em SharedPreferences de forma aberta.
Exemplo de vulnerabilidade:
val prefs = getSharedPreferences("app_prefs", Context.MODE_PRIVATE)prefs.edit().putString("auth_token", "secret123").apply() // Dados em texto claroComo corrigir:
// Use EncryptedSharedPreferences do AndroidX Securityval masterKey = MasterKey.Builder(context) .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) .build()val prefs = EncryptedSharedPreferences.create( context, "secure_prefs", masterKey, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM)prefs.edit().putString("auth_token", "secret123").apply()Recomendação: Para armazenar dados sensíveis, use EncryptedSharedPreferences ou KeyStore.
4. Vazamento de dados através de logs (Logging)
Desenvolvedores frequentemente deixam no código logs que exibem senhas, tokens ou dados pessoais de usuários.
Exemplo de vulnerabilidade:
Log.d("Auth", "User password: $password") // Senha vai para os logsComo corrigir:
// Use Timber ou um logger customizado com filtragemLog.d("Auth", "User authenticated successfully") // Não registramos dados sensíveisRecomendação: Ative ProGuard/R8 para remover logs em builds de release e use bibliotecas com mascaramento de dados (por exemplo, Timber).
5. WebView inseguros (Android)
WebView é um ponto de entrada frequente para ataques XSS e vazamento de dados, se JavaScript estiver ativado e filtros não estiverem configurados.