HIGH cwe 770koa

CWE-770 in Koa

How Cwe 770 Manifests in Koa

CWE-770: Allocation of Resources Without Limits or Throttling occurs when an application fails to restrict the number or size of resources allocated to a single user or process. In Koa.js applications, this manifests through several specific patterns that can lead to resource exhaustion attacks.

The most common manifestation in Koa involves file upload handling without size limits. Koa's body parser middleware, when configured without proper restrictions, allows attackers to upload arbitrarily large files:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx) => {
// Vulnerable: no file size limit
const file = ctx.request.files.file;
await file.mv(`./uploads/${file.name}`);
ctx.body = { success: true };
});

This code allows an attacker to upload files of any size, potentially exhausting disk space or memory. The vulnerability becomes more severe when combined with concurrent requests, as each request allocates its own buffer for file processing.

Another Koa-specific manifestation occurs in streaming operations without flow control. Koa's async/await pattern makes it easy to create unbounded memory consumption:

app.use(async (ctx) => {
const stream = fs.createReadStream('large-file.txt');

// Vulnerable: reading entire stream into memory
for await (const chunk of stream) {
data += chunk;
}
ctx.body = data;
});

This pattern reads an entire file into memory without limits, making the application vulnerable to memory exhaustion attacks. An attacker can request large files repeatedly, causing the Node.js process to consume excessive memory.

Connection pool exhaustion is another critical manifestation. Koa applications often use database connections without proper limits:

const db = require('database-library');

app.use(async (ctx) => {
// Vulnerable: no connection pooling limits
const connection = await db.connect();
const result = await connection.query('SELECT * FROM users');
connection.release();
ctx.body = result;
});

Without connection pool limits, an attacker can open numerous concurrent requests, exhausting the database connection pool and causing legitimate users to experience timeouts.

Rate limiting absence represents another critical vulnerability. Koa applications without rate limiting allow unlimited request processing:

app.use(async (ctx) => {
// Vulnerable: no rate limiting
await processHeavyOperation();
ctx.body = { result: 'done' };
});

This enables attackers to flood the application with requests, consuming CPU resources and potentially causing denial of service.

Koa-Specific Detection

Detecting CWE-770 vulnerabilities in Koa applications requires examining both the code structure and runtime behavior. The first step is analyzing middleware configuration for resource limits.

For file upload vulnerabilities, examine the body parser configuration:

const Koa = require('koa');
const app = new Koa();

// Check for missing limits
app.use(require('koa-body')({
multipart: true,
formidable: {
// Vulnerable if these limits are missing or too high
maxFileSize: 10 * 1024 * 1024, // 10MB limit
maxFieldsSize: 1 * 1024 * 1024 // 1MB limit
}
}));

Missing or excessively high limits for maxFileSize and maxFieldsSize indicate potential CWE-770 vulnerabilities. The default behavior of many body parser libraries is to accept unlimited file sizes, making explicit configuration essential.

Memory consumption patterns can be detected through code analysis. Look for streaming operations without backpressure handling:

function hasUnboundedMemoryConsumption(routeHandler) {
// Check for patterns like 'for await' without stream.pause/resume
const code = routeHandler.toString();
const hasAsyncIterator = /for await.*of.*stream/i.test(code);
const hasBackpressure = /stream/(pause|resume)/i.test(code);

return hasAsyncIterator && !hasBackpressure;
}

This detection pattern identifies Koa route handlers that read streams into memory without proper flow control mechanisms.

Database connection vulnerabilities are detected by examining connection acquisition patterns:

function hasUnboundedDatabaseConnections(routeHandler) {
const code = routeHandler.toString();
// Check for direct connection creation without pooling
const hasDirectConnect = /db\.connect\(\)/i.test(code);
const hasPoolConfig = /poolSize|connectionLimit/i.test(code);

return hasDirectConnect && !hasPoolConfig;
}

Applications that create database connections per request without connection pool limits are vulnerable to CWE-770.

Rate limiting detection involves examining middleware chains for rate limiting implementations:

function hasMissingRateLimiting(app) {
const middlewareNames = app.middleware.map(mw => mw.name);

name.includes('rateLimit') || name.includes('throttle')

return !hasRateLimiting;
}

Koa applications without rate limiting middleware in their middleware chain are vulnerable to request flooding attacks.

Automated scanning with middleBrick can detect these vulnerabilities by analyzing the running application:

npx middlebrick scan https://your-koa-app.com

The scan tests for resource exhaustion by sending large payloads, multiple concurrent requests, and monitoring resource consumption patterns. middleBrick's CWE-770 detection specifically looks for:

  • Missing file size limits in upload endpoints
  • Unbounded memory consumption in streaming operations
  • Database connection pool exhaustion vulnerabilities
  • Absence of rate limiting mechanisms
  • Infinite loop possibilities in request handlers

The scanner provides specific findings with severity levels and remediation guidance tailored to Koa applications.

Koa-Specific Remediation

Remediating CWE-770 vulnerabilities in Koa requires implementing proper resource limits and throttling mechanisms. The following solutions address each vulnerability pattern with Koa-specific implementations.

For file upload vulnerabilities, implement strict size limits using koa-body with proper configuration:

const Koa = require('koa');
const app = new Koa();
const koaBody = require('koa-body');

app.use(koaBody({
multipart: true,
formidable: {
maxFileSize: 5 * 1024 * 1024, // 5MB limit
maxFieldsSize: 1 * 1024 * 1024, // 1MB limit
maxFields: 10,
hash: 'sha1'
},
jsonLimit: '1mb',
formLimit: '1mb',
textLimit: '1mb'
}));

app.use(async (ctx) => {
if (ctx.request.files) {
// Process files with size validation
const file = ctx.request.files.file;
if (file.size > 5 * 1024 * 1024) {
ctx.status = 413;
ctx.body = { error: 'File too large' };
return;
}
await file.mv(`./uploads/${file.name}`);
}
ctx.body = { success: true };
});

This configuration enforces strict limits on file sizes, form data, and JSON payloads. The maxFileSize parameter prevents large file uploads, while jsonLimit, formLimit, and textLimit protect against large request bodies.

For memory consumption vulnerabilities in streaming operations, implement proper backpressure handling:

const pump = require('pump');

app.use(async (ctx) => {
const stream = fs.createReadStream('large-file.txt');

// Use pump for proper error handling and backpressure
ctx.body = await new Promise((resolve, reject) => {
pump(stream, ctx.res, (err) => {
if (err) reject(err);
else resolve();
});
});
});

The pump library handles backpressure automatically, preventing memory exhaustion by pausing the read stream when the write stream cannot keep up.

Database connection vulnerabilities are remediated using connection pooling with proper limits:

const mysql = require('mysql2/promise');

const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'password',
database: 'test',
connectionLimit: 10, // Limit concurrent connections
queueLimit: 50, // Limit waiting requests
acquireTimeout: 10000,
});

app.use(async (ctx) => {
try {
const [rows] = await pool.query('SELECT * FROM users');
ctx.body = rows;
} catch (err) {
ctx.status = 500;
ctx.body = { error: 'Database connection failed' };
}
});

This configuration limits the connection pool to 10 concurrent connections and queues up to 50 waiting requests, preventing connection exhaustion attacks.

Rate limiting is implemented using koa-ratelimit:

const Koa = require('koa');
const app = new Koa();
const ratelimit = require('koa-ratelimit');
const Redis = require('ioredis');

const redis = new Redis();

app.use(ratelimit({
driver: 'redis',
db: redis,
duration: 60000, // 1 minute window
errorMessage: 'Too many requests',
id: (ctx) => ctx.ip,
headers: {
remaining: 'X-RateLimit-Remaining',
reset: 'X-RateLimit-Reset',
total: 'X-RateLimit-Limit'
},
max: 100 // 100 requests per minute
}));

app.use(async (ctx) => {
ctx.body = { message: 'Hello World' };
});

This rate limiting implementation uses Redis for distributed rate limiting, allowing 100 requests per minute per IP address. The middleware automatically returns HTTP 429 responses when limits are exceeded.

For comprehensive protection, combine multiple middleware layers:

const Koa = require('koa');
const app = new Koa();

// Security middleware chain
app.use(koaBody({
multipart: true,
formidable: { maxFileSize: 5 * 1024 * 1024 }
}));

app.use(ratelimit({
driver: 'memory',
duration: 60000,
max: 100,
id: (ctx) => ctx.ip
}));

app.use(async (ctx, next) => {
const startTime = Date.now();
await next();
const duration = Date.now() - startTime;

// Log and monitor resource usage
console.log(`${ctx.method} ${ctx.url} - ${duration}ms`);
});

This layered approach provides defense in depth against CWE-770 vulnerabilities by combining file size limits, rate limiting, and resource monitoring.

Frequently Asked Questions

How can I test if my Koa application is vulnerable to CWE-770?
Test your Koa application by sending large file uploads exceeding typical limits (10MB+), making numerous concurrent requests to test rate limiting, and monitoring memory usage during streaming operations. Use middleBrick's automated scanning to identify specific CWE-770 vulnerabilities with severity ratings and remediation guidance.
What's the difference between koa-body and koa-multer for file uploads in Koa?
koa-body is a general-purpose body parser that handles JSON, form data, and file uploads with built-in size limits. koa-multer is specifically designed for file uploads and provides more granular control over file handling, storage, and validation. Both can prevent CWE-770 when properly configured with size limits.