GuardAPI Logo
GuardAPI

Fix NoSQL Injection in Koa

NoSQL Injection in Koa environments occurs when untrusted input from 'ctx.request.body' or 'ctx.query' is passed directly into database query filters. Since Koa's body-parsers handle JSON objects, an attacker can substitute a string with a nested object containing MongoDB operators like $gt, $ne, or $regex. This allows for authentication bypass, data exfiltration, and logic manipulation. If you aren't sanitizing your input objects, you're leaving the door wide open for database takeover.

The Vulnerable Pattern

const Koa = require('koa');
const Router = require('@koa/router');
const bodyParser = require('koa-bodyparser');
const { MongoClient } = require('mongodb');

const app = new Koa(); const router = new Router(); app.use(bodyParser());

// VULNERABLE: Attacker can inject operators via JSON body router.post(‘/api/v1/login’, async (ctx) => { const { username, password } = ctx.request.body;

// If attacker sends {“username”: “admin”, “password”: {“$ne”: ""}}, // the query returns the first user where password is not empty. const user = await ctx.db.collection(‘users’).findOne({ username, password });

if (user) { ctx.body = { status: ‘success’, token: ‘secret_session_token’ }; } else { ctx.status = 401; ctx.body = { error: ‘Unauthorized’ }; } });

The Secure Implementation

To mitigate NoSQL injection in Koa, you must implement two layers of defense. First, use a library like 'mongo-sanitize' to recursively remove any keys starting with '$' from the request object; this prevents operator injection. Second, implement strict type validation. In the secure example, we verify that 'username' and 'password' are primitive strings. This prevents an attacker from passing an object even if it doesn't contain a '$' sign. For larger projects, using a validation schema (like Joi or Zod) to enforce strict input shapes is the gold standard.

const Koa = require('koa');
const Router = require('@koa/router');
const bodyParser = require('koa-bodyparser');
const sanitize = require('mongo-sanitize');

const app = new Koa(); const router = new Router(); app.use(bodyParser());

// SECURE: Strict type checking and sanitization router.post(‘/api/v1/login’, async (ctx) => { // 1. Sanitize the entire body to strip any keys starting with $ const cleanBody = sanitize(ctx.request.body);

const { username, password } = cleanBody;

// 2. Enforce type constraints - ensure inputs are strings, not objects if (typeof username !== ‘string’ || typeof password !== ‘string’) { ctx.status = 400; ctx.body = { error: ‘Invalid input types’ }; return; }

const user = await ctx.db.collection(‘users’).findOne({ username: username, password: password });

if (user) { ctx.body = { status: ‘success’ }; } else { ctx.status = 401; } });

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

Your Koa API might be exposed to NoSQL Injection

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.