GuardAPI Logo
GuardAPI

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()

System Alert • ID: 2616
Target: Ktor API
Potential Vulnerability

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.

RUN FREE SECURITY DIAGNOSTIC
GuardLabs Engine: ONLINE

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.