GuardAPI Logo
GuardAPI

Fix SQL Injection (Legacy & Modern) in Koa

SQL Injection in Koa is a classic failure of input sanitization and query construction. When you allow raw user input from 'ctx.request.body' or 'ctx.query' to be concatenated directly into your SQL strings, you're handing over your database keys to any script kiddie with a copy of sqlmap. In modern Node.js environments, there is zero excuse for this. You either use parameterized queries or a type-safe ORM/Query Builder that handles bindings for you.

The Vulnerable Pattern

const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
const mysql = require('mysql2/promise');
const app = new Koa();
app.use(bodyParser());

app.use(async (ctx) => { if (ctx.path === ‘/login’ && ctx.method === ‘POST’) { const { username, password } = ctx.request.body; const db = await mysql.createConnection(config); // VULNERABLE: Template literals allow an attacker to escape the query // Payload: admin’ — const [rows] = await db.execute(SELECT * FROM users WHERE user = '${username}' AND pass = '${password}'); ctx.body = rows; } });

The Secure Implementation

The fix relies on 'Prepared Statements'. By using placeholders (?), the database driver sends the SQL template and the data in two separate steps. The database engine parses the query logic first, then treats the user-provided parameters strictly as literal data. Even if the 'username' contains SQL commands like 'DROP TABLE', it is treated as a harmless string. For modern Koa apps, it is highly recommended to use a Query Builder like Knex.js (e.g., knex('users').where({ user: username })) or an ORM like Prisma, which implement these protections by default.

const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
const mysql = require('mysql2/promise');
const app = new Koa();
app.use(bodyParser());

app.use(async (ctx) => { if (ctx.path === ‘/login’ && ctx.method === ‘POST’) { const { username, password } = ctx.request.body; const db = await mysql.createConnection(config); // SECURE: Parameterized queries (Prepared Statements) // The ’?’ acts as a placeholder; data is sent separately from the command const [rows] = await db.execute(‘SELECT * FROM users WHERE user = ? AND pass = ?’, [username, password]); ctx.body = rows; } });

System Alert • ID: 7462
Target: Koa API
Potential Vulnerability

Your Koa API might be exposed to SQL Injection (Legacy & Modern)

74% of Koa 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.