Kotlin Application Security: Top 10 Vulnerabilities

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction



Kotlin is a modern programming language actively used for developing Android applications, server-side solutions (Ktor, Spring Boot) and cross-platform projects. Despite its strong typing and null-safety, developers often make mistakes that lead to serious vulnerabilities. In this article, we will analyze the top 10 vulnerabilities of Kotlin applications, based on OWASP standards, and show how to avoid them.



This article will be useful for both beginner and experienced Kotlin developers looking to improve the security level of their projects.



1. SQL Injection



Problem: Injection of malicious SQL code through user input.



Example of vulnerable code:



// Vulnerable! Do not use string concatenationfun getUserById(id: String): User? {    val query = "SELECT * FROM users WHERE id = '$id'"    val result = connection.createStatement().executeQuery(query)    return result.toUser()}


Solution: Use parameterized queries (PreparedStatement).



// Safefun getUserById(id: String): User? {    val query = "SELECT * FROM users WHERE id = ?"    val preparedStatement = connection.prepareStatement(query)    preparedStatement.setString(1, id)    val result = preparedStatement.executeQuery()    return result.toUser()}


2. Cross-Site Scripting (XSS)



Problem: Insertion of malicious JavaScript code into a web page.



Example of vulnerable code (Ktor):



// Vulnerable! Do not escape outputget("/search") {    val query = call.parameters["q"] ?: ""    call.respondHtml {        h1 { +"Search results for: $query" } // XSS!    }}


Solution: Use HTML escaping (e.g., kotlinx.html with escaping).



// Safeimport kotlinx.html.escapeHtml

get("/search") { val query = call.parameters["q"] ?: "" val safeQuery = query.escapeHtml() call.respondHtml { h1 { +"Search results for: $safeQuery" } }}


3. Insecure Password Storage



Problem: Storing passwords in plain text or using weak hashes (MD5, SHA-1).



Example of vulnerable code:



// Vulnerable! MD5 is not suitable for passwordsfun saveUser(password: String) {    val hash = MessageDigest.getInstance("MD5").digest(password.toByteArray())    // save hash in DB}


Solution: Use bcrypt, scrypt, or Argon2.



// Safe (using jbcrypt library)import org.mindrot.jbcrypt.BCrypt

fun hashPassword(password: String): String { return BCrypt.hashpw(password, BCrypt.gensalt(12))}

fun checkPassword(password: String, hashed: String): Boolean { return BCrypt.checkpw(password, hashed)}


4. Leakage of Confidential Data via Logs



Problem: Logging passwords, tokens, card numbers.



Example of vulnerable code:



// Vulnerable! Logging sensitive datafun login(username: String, password: String) {    log.info("Login attempt: username=$username, password=$password")}


Solution: Use filters or masking.



// Safefun login(username: String, password: String) {    log.info("Login attempt: username=$username")    // password is not logged}


5. Insecure Deserialization



Problem: Execution of arbitrary code during deserialization of untrusted data.



Example of vulnerable code:



// Vulnerable! Deserialization without validationfun process                

Blogs

Book Recommendations