Kotlin Application Security: Top 10 Vulnerabilities in Practice

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

Kotlin Application Security: Top 10 Vulnerabilities in Practice

Kotlin confidently holds its position as one of the most popular languages for Android and server application development. However, like any other language, Kotlin is not immune to vulnerabilities. In this article, we will analyze the top 10 most critical security issues that developers face and show how to avoid them in practice.



1. SQL Injection

Despite Kotlin being frequently used with ORM libraries, direct work with SQL queries remains a common practice.

Vulnerable Code:

fun getUser(id: String): User? {    val query = "SELECT * FROM users WHERE id = '$id'"    val result = connection.createStatement().executeQuery(query)    // ...}

Secure Version (using PreparedStatement):

fun getUserSafe(id: String): User? {    val query = "SELECT * FROM users WHERE id = ?"    val stmt = connection.prepareStatement(query)    stmt.setString(1, id)    val result = stmt.executeQuery()    // ...}

Conclusion: Never concatenate user input into SQL queries. Use parameterized queries or ORM (Exposed, Hibernate).



2. Cross-Site Scripting (XSS) in Web Applications

When developing server applications with Ktor or Spring Boot, developers often forget to escape output.

Vulnerable Code (Ktor):

get("/user/{name}") {    val name = call.parameters["name"] ?: "Guest"    call.respondText("<h1>Hello, $name!</h1>", ContentType.Text.Html)}

Secure Version:

import org.apache.commons.text.StringEscapeUtils

get("/user/{name}") { val name = call.parameters["name"] ?: "Guest" val safeName = StringEscapeUtils.escapeHtml4(name) call.respondText("<h1>Hello, $safeName!</h1>", ContentType.Text.Html)}

Tip: Always escape user input before outputting it in HTML. Use template engines with auto-escaping (e.g., Kotlinx.html).



3. Insecure Password Storage

Storing passwords in plaintext or using weak hashes is one of the most common mistakes.

Wrong Approach:

fun savePassword(password: String) {    val hash = password.md5() // Never do this!    database.saveHash(hash)}

Correct Approach (bcrypt):

import at.favre.lib.crypto.bcrypt.BCrypt

fun savePassword(password: String) { val hash = BCrypt.withDefaults().hashToString(12, password.toCharArray()) database.saveHash(hash)}

fun checkPassword(password: String, storedHash: String): Boolean { return BCrypt.verifyer().verify(password.toCharArray(), storedHash).verified}

Important: Use bcrypt, scrypt, or Argon2. Never use MD5 or SHA-1 for storing passwords.



4. Leakage of Confidential Data Through Logs

Developers often log sensitive data without checking what ends up in the output.

Problematic Code:

logger.info("User $userId authorized with token: $token")

Secure Version:

logger.info("User $userId authorized successfully")// Or use masking:fun maskToken(token: String): String =     token.take(4) + "****" + token.takeLast(4)

Rule: Never log passwords, tokens, credit card numbers, or personal data. Use masking libraries (e.g., Logstash).



5. Insecure Deserialization

Kotlin actively uses JSON serialization. Incorrect configuration can lead to RCE attacks.

Vulnerable Code (Jackson):

val mapper = ObjectMapper()val obj = mapper.readValue(userInput, Any::class.j                

Blogs

Book Recommendations