Integer Overflow in Feathersjs
How Integer Overflow Manifests in Feathersjs
Integer overflow vulnerabilities in Feathersjs applications typically occur when numeric values from user input are processed without proper validation or type checking. In JavaScript/TypeScript (which Feathersjs is built on), numbers are represented as 64-bit floating point values, but integer operations can still overflow when values exceed safe integer limits or when calculations produce results outside expected ranges.
A common Feathersjs-specific scenario involves pagination parameters. Consider a service that accepts page and limit parameters:
const getItems = async (req, res) => {
const { page = 1, limit = 10 } = req.query;
const skip = (page - 1) * limit; // Vulnerable to overflow
const items = await db.collection('items').find().skip(skip).limit(limit);
res.json(items);
}If an attacker supplies page=1000000000 and limit=1000000000, the multiplication (page-1)*limit could produce a number exceeding JavaScript's safe integer range (2^53 - 1), leading to precision loss or unexpected behavior. In database queries, this might result in skipping fewer records than intended or causing the query to fail entirely.
Another Feathersjs-specific pattern involves ID-based resource access. Many Feathersjs applications use MongoDB or similar databases where IDs might be numeric:
const getItem = async (req, res) => {
const id = parseInt(req.params.id);
const item = await db.collection('items').findOne({ _id: id });
res.json(item);
}If an attacker provides a very large numeric ID, parseInt might succeed but the database query could behave unexpectedly due to integer overflow in the underlying database driver. MongoDB's BSON format uses 64-bit integers, so values exceeding this range could cause errors or security bypasses.
Financial calculations in Feathersjs services present another risk. Consider a payment processing service:
const processPayment = async (req, res) => {
const { amount, currency } = req.body;
const total = amount * exchangeRates[currency]; // Overflow possible
await db.collection('payments').insertOne({ amount, total, currency });
res.json({ success: true });
}Large monetary values multiplied by exchange rates could overflow, resulting in incorrect totals that might be exploited for financial gain. The lack of explicit integer type checking in JavaScript means these overflows often go undetected until they cause business logic failures.
Feathersjs hooks can also introduce overflow vulnerabilities when processing numeric data. A before hook that modifies numeric fields:
module.exports = async context => {
const { data } = context;
data.quantity = data.quantity * context.params.query.multiplier;
return context;
}If the multiplier parameter comes from user input and the quantity field contains large values, the multiplication could overflow, leading to incorrect data being stored in the database.
Feathersjs-Specific Detection
Detecting integer overflow vulnerabilities in Feathersjs applications requires both static analysis of the codebase and dynamic testing of the running application. For static analysis, look for patterns where numeric operations occur on user-controlled input without validation.
Code review should focus on service files, hooks, and any middleware that processes numeric parameters. Search for these patterns:
// Vulnerable patterns to flag:
const result = userValue * someFactor; // Multiplication
const result = userValue + offset; // Addition
const result = Math.pow(base, exponent); // Exponentiation
const id = parseInt(req.params.id); // String to int conversion
const num = Number(req.query.value); // String to number conversion
Dynamic testing with middleBrick can automatically identify these vulnerabilities by scanning your Feathersjs API endpoints. middleBrick's Input Validation check specifically tests for numeric parameter handling by submitting boundary values that could trigger overflows.
For Feathersjs applications, middleBrick tests common pagination parameters (page, limit, offset) with extremely large values to detect overflow handling issues. The scanner also tests ID parameters by submitting numeric strings that exceed typical ranges, checking if the application properly validates or sanitizes these inputs.
middleBrick's Property Authorization check examines whether numeric properties in request bodies are properly validated before being used in calculations or database operations. For a Feathersjs service like:
const createOrder = async (req, res) => {
const { productId, quantity, price } = req.body;
const total = quantity * price; // Potential overflow
await db.collection('orders').insertOne({ productId, quantity, price, total });
res.json({ success: true });
}middleBrick would test this endpoint with extremely large quantity and price values to verify that the application handles overflow cases appropriately, either by rejecting the input or correctly handling the calculation.
The scanner also examines OpenAPI specifications for Feathersjs applications to identify numeric parameters and properties that lack proper validation constraints. If your Feathersjs app exposes an OpenAPI spec, middleBrick cross-references the spec definitions with its runtime findings to provide comprehensive coverage.
For continuous monitoring, the middleBrick GitHub Action can be configured to scan your Feathersjs API whenever code changes are pushed. This ensures that new endpoints or modified services don't introduce integer overflow vulnerabilities without detection.
Feathersjs-Specific Remediation
Remediating integer overflow vulnerabilities in Feathersjs applications requires a combination of input validation, safe numeric operations, and proper error handling. The most effective approach is to validate all numeric input against expected ranges before processing.
For pagination parameters in Feathersjs services, implement strict validation:
const validatePagination = (page, limit) => {
const maxPage = 1000;
const maxLimit = 100;
const pageNum = parseInt(page);
const limitNum = parseInt(limit);
if (isNaN(pageNum) || isNaN(limitNum)) {
throw new Error('Invalid pagination parameters');
}
if (pageNum < 1 || pageNum > maxPage) {
throw new Error('Page out of valid range');
}
if (limitNum < 1 || limitNum > maxLimit) {
throw new Error('Limit out of valid range');
}
return { page: pageNum, limit: limitNum };
};
const getItems = async (req, res) => {
try {
const { page = 1, limit = 10 } = req.query;
const { page: pageNum, limit: limitNum } = validatePagination(page, limit);
const skip = (pageNum - 1) * limitNum;
const items = await db.collection('items').find().skip(skip).limit(limitNum);
res.json(items);
} catch (error) {
res.status(400).json({ error: error.message });
}
};
For ID parameters, use type-safe validation with explicit range checking:
const validateId = id => {
const numId = parseInt(id);
if (isNaN(numId)) {
throw new Error('ID must be a number');
}
if (numId < 0 || numId > Number.MAX_SAFE_INTEGER) {
throw new Error('ID out of valid range');
}
return numId;
};
const getItem = async (req, res) => {
try {
const id = validateId(req.params.id);
const item = await db.collection('items').findOne({ __id: id });
if (!item) {
return res.status(404).json({ error: 'Item not found' });
}
res.json(item);
} catch (error) {
res.status(400).json({ error: error.message });
}
};
For financial calculations, use a decimal library to avoid floating-point precision issues and implement safe arithmetic:
const Decimal = require('decimal.js');
const processPayment = async (req, res) => {
try {
const { amount, currency } = req.body;
const amountDec = new Decimal(amount);
if (amountDec.isNaN() || amountDec.lte(0)) {
throw new Error('Invalid amount');
}
if (amountDec.gt(new Decimal('1000000'))) {
throw new Error('Amount exceeds maximum allowed value');
}
const exchangeRate = new Decimal(exchangeRates[currency]);
const total = amountDec.times(exchangeRate);
await db.collection('payments').insertOne({
amount: amountDec.toString(),
total: total.toString(),
currency
});
res.json({ success: true });
} catch (error) {
res.status(400).json({ error: error.message });
}
};
Implement comprehensive validation hooks in Feathersjs to centralize numeric validation logic:
const numericValidationHook = field => context => {
const value = context.data[field];
if (value === undefined || value === null) {
return context;
}
const numValue = Number(value);
if (isNaN(numValue)) {
throw new Error(`${field} must be a number`);
}
if (numValue < 0 || numValue > Number.MAX_SAFE_INTEGER) {
throw new Error(`${field} out of valid range`);
}
context.data[field] = numValue;
return context;
};
module.exports = {
before: {
create: [
numericValidationHook('quantity'),
numericValidationHook('price'),
numericValidationHook('discount')
],
update: [
numericValidationHook('quantity'),
numericValidationHook('price')
]
}
};
For continuous protection, integrate middleBrick into your Feathersjs development workflow. The middleBrick CLI can be run locally during development:
npm install -g middlebrick
middlebrick scan https://your-feathersjs-api.com
This provides immediate feedback on potential integer overflow vulnerabilities before code reaches production. For production applications, the middleBrick GitHub Action can automatically scan your API endpoints on each pull request, ensuring that new code doesn't introduce vulnerabilities.