Fix SQL Injection (Legacy & Modern) in Ktor
Ktor's flexibility is a double-edged sword. If you're manually concatenating strings into raw SQL queries inside your routes or DAOs, you're inviting full database compromise. SQL Injection (SQLi) in Ktor typically occurs when developers bypass the Exposed DSL or use raw JDBC incorrectly. To secure a Ktor app, you must move from string interpolation to type-safe DSLs or parameterized prepared statements.
The Vulnerable Pattern
// VULNERABLE: Raw string interpolation in Exposed exec() val userId = call.parameters["id"] transaction { val query = "SELECT * FROM users WHERE id = '$userId'" exec(query) { rs -> // Mapping results here... } }
// VULNERABLE: Raw JDBC concatenation val conn = dataSource.connection val stmt = conn.createStatement() val rs = stmt.executeQuery(“SELECT * FROM users WHERE username = ’” + inputName + ”’”)
The Secure Implementation
The vulnerability lies in treating user-controlled input as executable code. In the vulnerable examples, an attacker could provide an ID like "1' OR '1'='1", bypassing authentication or dumping the entire table. The secure approach uses 'Prepared Statements'. By using the Exposed DSL (eq, select, etc.) or passing an 'args' list to exec(), the database driver treats the input as a literal value rather than part of the SQL command. This effectively neutralizes the injection vector by pre-compiling the SQL structure and binding the data separately.
// SECURE: Using Exposed Type-Safe DSL (Recommended) val userId = call.parameters["id"]?.toIntOrNull() ?: return@get call.respond(HttpStatusCode.BadRequest) val user = transaction { Users.select { Users.id eq userId }.map { it[Users.name] }.firstOrNull() }// SECURE: Parameterized Raw SQL in Exposed transaction { exec(“SELECT * FROM users WHERE id = ?”, args = listOf(IntColumnType() to userId)) { rs -> // Process results safely } }
// SECURE: Standard JDBC Prepared Statements val pstmt = conn.prepareStatement(“SELECT * FROM users WHERE username = ?”) pstmt.setString(1, inputName) val rs = pstmt.executeQuery()
Your Ktor API
might be exposed to SQL Injection (Legacy & Modern)
74% of Ktor apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.