Seu código na mira: por que segurança em Kotlin não é opção, mas necessidade
\n\nImagine: você escreveu o aplicativo perfeito. Interface bonita, velocidade relâmpago, arquitetura limpa. Mas em uma linha de código se esconde uma "porta dos fundos". Um invasor digita no campo de busca ' OR '1'='1 — e seu banco de dados está aberto como uma lata de sardinha. Familiar? Se não — ótimo. Mas é melhor estar preparado com antecedência do que apagar incêndios em produção.
Kotlin é uma linguagem poderosa e moderna. Mas, como qualquer outra ferramenta, ela não torna seu código seguro por padrão. Injeções SQL e XSS (Cross-Site Scripting) continuam no topo do OWASP Top 10 há muitos anos. E desenvolvedores Kotlin que pensam "estou usando ORM, não corro risco" frequentemente se encontram na zona de perigo.
\n\nNeste artigo, vamos analisar como transformar seu código Kotlin em uma fortaleza inexpugnável. Sem enrolação — apenas dicas práticas, exemplos reais e truques que você pode aplicar ainda hoje.
\n\nInjeções SQL em Kotlin: anatomia do ataque e estratégias de defesa
\n\nComo é a vulnerabilidade (e por que é assustadora)
\n\nUma injeção SQL ocorre quando a entrada do usuário vai diretamente para uma consulta SQL. Suponha que você tenha este código (nunca faça isso!):
\n\nfun getUserById(id: String): User? {\n val query = "SELECT * FROM users WHERE id = '$id'"\n val statement = connection.createStatement()\n val result = statement.executeQuery(query)\n // ...\n}\n\nSe um invasor passar id = "1'; DROP TABLE users; --", o banco de dados executará: SELECT * FROM users WHERE id = '1'; DROP TABLE users; --'. E seus usuários desaparecerão. Para sempre.
Regra nº1: Sempre use consultas parametrizadas
\n\nEste é o padrão ouro. Kotlin (e Java) fornece PreparedStatement, que separa o código SQL dos dados:
fun getUserByIdSafe(id: String): User? {\n val query = "SELECT * FROM users WHERE id = ?"\n val preparedStatement = connection.prepareStatement(query)\n preparedStatement.setString(1, id)\n val result = preparedStatement.executeQuery()\n // ...\n}\n\nO banco de dados recebe o modelo da consulta separadamente dos dados. Mesmo que um código malicioso chegue no id, ele será interpretado como string, não como comando.
Regra nº2: Use Exposed ou outros ORMs corretamente
\n\nA biblioteca Exposed é uma escolha popular para Kotlin. Ela é segura se você usar sua API corretamente. Exemplo ruim (concatenação bruta):
\n\n// RUIM: vulnerabilidade\nval users = transaction {\n exec("SELECT * FROM users WHERE name = '$userInput'")\n}\n\nExemplo bom (usando DSL do Exposed):
\n\n// BOM: sanitização embutida\nval users = transaction {\n Users.select { Users.name eq userInput }\n}\n\nNo Exposed, o operador eq sanitiza automaticamente os valores. Mas se você escrever consultas SQL brutas através de exec — fique atento.
Regra nº3: Validação na entrada — seu segundo escudo
\n\nMesmo com consultas parametrizadas, não deixe tudo entrar no banco. Use os recursos nativos do Kotlin para verificação:
\n\nfun validateUserId(id: String): Boolean {\n // Verifica se id é um UUID ou número inteiro\n return id.matches(Regex("^[a-fA-F0-9-]{36}$")) || \n id.all { it.isDigit() }\n}\n\nLembre-se: não confie em nenhuma entrada. Mesmo que venha do seu próprio frontend. Especialmente se vier do seu próprio frontend.
\n\nAtaques XSS: como não deixar o código JavaScript dominar seu site
\n\nO que é XSS e por que Kotlin não protege você automaticamente
\n\nXSS (Cross-Site Scripting) é quando um invasor insere um script na sua página. Por exemplo, no campo de comentário ele escreve: <script>alert('Seus dados foram roubados')</script>