Kotlin and Security: How to Forget About SQL Injections and XSS

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

Your Code is in the Crosshairs: Why Security in Kotlin is Not an Option, but a Necessity

\n\n

Imagine: you've written a perfect application. A beautiful interface, lightning-fast speed, clean architecture. But in one line of code, a "backdoor" is hiding. An attacker enters ' OR '1'='1 into the search field — and your database is open like a can of sardines. Sound familiar? If not — great. But it's better to be prepared in advance than to put out a fire in production.

\n\n

Kotlin is a powerful and modern language. But, like any other tool, it doesn't make your code secure by default. SQL injections and XSS (Cross-Site Scripting) have been in the top of the OWASP Top 10 for many years. And Kotlin developers who think "I'm using an ORM, I have nothing to worry about" often find themselves in the risk zone.

\n\n

In this article, we'll break down how to turn your Kotlin code into an impregnable fortress. No fluff — only practical advice, real examples, and life hacks you can apply today.

\n\n

SQL Injections in Kotlin: Anatomy of an Attack and Defense Strategies

\n\n

What a Vulnerability Looks Like (and Why It's Scary)

\n\n

An SQL injection occurs when user input goes directly into an SQL query. Suppose you have code like this (never do this!):

\n\n
fun 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\n

If an attacker passes id = "1'; DROP TABLE users; --", the database will execute: SELECT * FROM users WHERE id = '1'; DROP TABLE users; --'. And your users will disappear. Irreversibly.

\n\n

Rule #1: Always Use Parameterized Queries

\n\n

This is the gold standard. Kotlin (and Java) provides PreparedStatement, which separates SQL code and data:

\n\n
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\n

The database receives the query template separately from the data. Even if malicious code arrives in id, it will be interpreted as a string, not as a command.

\n\n

Rule #2: Use Exposed or Other ORMs Correctly

\n\n

The Exposed library is a popular choice for Kotlin. It is safe if you use its API correctly. Bad example (raw concatenation):

\n\n
// BAD: vulnerability\nval users = transaction {\n    exec("SELECT * FROM users WHERE name = '$userInput'")\n}
\n\n

Good example (using Exposed DSL):

\n\n
// GOOD: escaping is built-in\nval users = transaction {\n    Users.select { Users.name eq userInput }\n}
\n\n

In Exposed, the eq operator automatically escapes values. But if you write raw SQL queries via exec — be vigilant.

\n\n

Rule #3: Input Validation is Your Second Shield

\n\n

Even with parameterized queries, you shouldn't let everything into the database. Use Kotlin's built-in tools for validation:

\n\n
fun validateUserId(id: String): Boolean {\n    // Check that id is a UUID or an integer\n    return id.matches(Regex("^[a-fA-F0-9-]{36}$")) || \n           id.all { it.isDigit() }\n}
\n\n

Remember: trust no input. Even if it comes from your own frontend. Especially if it comes from your own frontend.

\n\n

XSS Attacks: How to Prevent JavaScript Code from Hijacking Your Site

\n\n

What is XSS and Why Kotlin Doesn't Protect You Automatically

\n\n

XSS (Cross-Site Scripting) is when an attacker injects a script onto your page. For example, in a comment field, they write: <script>alert('Your data has been stolen')</script>

Blogs

Book Recommendations