HIGH http request smugglingfeathersjs

Http Request Smuggling in Feathersjs

How Http Request Smuggling Manifests in Feathersjs

Http Request Smuggling in Feathersjs applications typically occurs at the boundary between different HTTP components or when handling multipart requests. The issue arises when Feathersjs processes requests differently than the reverse proxy or load balancer, creating ambiguity about where one request ends and another begins.

A common scenario involves Feathersjs's multipart middleware combined with Express body parsing. Consider this vulnerable setup:

const express = require('express');
const feathers = require('@feathersjs/feathers');
const bodyParser = require('body-parser');
const multer = require('multer');

const app = express(feathers());

// Vulnerable ordering - body-parser executes before multer
app.use(bodyParser.json());
app.use(multer().any());

app.post('/upload', async (req, res) => {
// Feathers service handling

In this configuration, Express's bodyParser.json() processes the request first, but if the Content-Type is ambiguous or malformed, the multipart parser may interpret the request boundaries differently. An attacker can craft a payload like:

POST /upload HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 4

{}
POST /admin/delete HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 23

user=admin&delete=true

The first Content-Length: 4 suggests a 4-byte JSON body, but the actual payload contains more data. Depending on how the Feathersjs middleware chain processes this, the second request might be interpreted as part of the first, leading to smuggling.

Another Feathers-specific vulnerability occurs with the @feathersjs/transport-commons real-time transport layer. When combining HTTP REST endpoints with WebSocket connections, inconsistencies in how Content-Length and Transfer-Encoding headers are handled can create smuggling opportunities:

const { app } = require('@feathersjs/express');
const socketio = require('@feathersjs/socketio');

const api = express();
api.use(bodyParser.json());
api.use('/messages', messagesService);

const server = http.createServer(api);
socketio(server); // Socket.io adds its own parsing layer

The interaction between Express body parsing, Socket.io's WebSocket handshake, and Feathers services can create parsing ambiguities, especially when clients manipulate Transfer-Encoding headers to trigger chunked encoding misinterpretation.

Feathersjs-Specific Detection

Detecting Http Request Smuggling in Feathersjs requires examining both the application code and runtime behavior. Start by analyzing your middleware stack for parsing inconsistencies:

# Check for vulnerable middleware ordering
node -e "
const app = require('./app');
const layers = app._router.stack;
layers.forEach((layer, i) => {
console.log(i, layer.name, layer.regexp);
});
"

Look for patterns where body parsers execute before multipart parsers, or where multiple parsers could conflict. The Feathers CLI-generated applications often include this vulnerability by default.

For runtime detection, use a tool like middleBrick to scan your Feathersjs API endpoints. middleBrick's black-box scanning approach tests the unauthenticated attack surface by sending specially crafted requests that probe for smuggling vulnerabilities:

npm install -g middlebrick

# Scan your Feathersjs API
middlebrick scan http://localhost:3030

middleBrick tests for smuggling by sending requests with manipulated Content-Length and Transfer-Encoding headers, then analyzing the server's response to detect ambiguity. The scanner checks if the server processes requests in a way that could allow request smuggling, providing a security risk score and specific findings.

Manual testing involves sending crafted requests through your Feathersjs application:

const axios = require('axios');

const testSmuggling = async () => {
const payload = `POST /test HTTP/1.1\r\n` +
`Host: localhost:3030\r\n` +
`Content-Type: application/json\r\n` +
`Content-Length: 4\r\n` +
`\r\n` +
`{}` +
`GET /admin HTTP/1.1\r\n` +
`Host: localhost:3030\r\n` +
`\r\n`;

try {
const response = await axios.post('http://localhost:3030/', payload, {
headers: { 'Content-Type': 'application/http' }
});
console.log('Response:', response.data);
} catch (error) {
console.error('Test failed:', error.message);
}
};

Monitor your Feathersjs logs and error tracking to identify parsing errors or unexpected behavior when processing ambiguous requests.

Feathersjs-Specific Remediation

Fixing Http Request Smuggling in Feathersjs applications requires addressing both middleware configuration and request parsing consistency. Start with middleware ordering and configuration:

const express = require('express');
const feathers = require('@feathersjs/feathers');
const bodyParser = require('body-parser');
const multer = require('multer');

const app = express(feathers());

// Use a single, consistent body parser
app.use(bodyParser.json({ strict: true }));
app.use(bodyParser.urlencoded({ extended: false }));

// Configure multer with strict limits and type checking
const upload = multer({
limits: {
fileSize: 1000000, // 1MB limit
files: 1
},
fileFilter: (req, file, cb) => {
if (file.mimetype !== 'application/json') {
return cb(new Error('Invalid file type'));
}
cb(null, true);
}
});

// Use a single, consistent entry point for multipart
app.use('/upload', upload.single('file'), async (req, res) => {
// Process file securely

The key is using strict parsing options and avoiding multiple parsers that could conflict. Configure Express to reject ambiguous requests:

app.use((req, res, next) => {
// Reject requests with both Content-Length and Transfer-Encoding
return res.status(400).json({ error: 'Ambiguous content encoding' });
}
next();

For Feathers services, implement input validation at the service level:

const { BadRequest } = require('@feathersjs/errors');

class MessagesService {
async create(data, params) {
// Validate request structure
if (typeof data !== 'object' || data === null) {
throw new BadRequest('Invalid request format');
}
// Additional validation
}
}

When using transports like Socket.io with Feathers, configure strict parsing:

const socketio = require('@feathersjs/socketio');

app.configure(socketio(function(io) {
io.use((socket, next) => {
// Validate handshake data
return next(new Error('Authentication required'));
}
next();
});
}));

For production deployments, ensure your reverse proxy and Feathers application agree on parsing rules. Configure your proxy to use a single, consistent parsing strategy and validate that it matches your Feathers configuration.

Frequently Asked Questions

How can I test my Feathersjs API for Http Request Smuggling vulnerabilities?
Use middleBrick's black-box scanning to test your API endpoints without requiring credentials or access to source code. The scanner sends specially crafted requests with manipulated headers to detect smuggling vulnerabilities. You can also perform manual testing by sending requests with conflicting Content-Length and Transfer-Encoding headers, or by testing multipart request boundaries. Monitor your application logs for parsing errors or unexpected behavior when processing these crafted requests.
Does middleBrick detect Http Request Smuggling in Feathersjs applications?
Yes, middleBrick scans Feathersjs APIs for Http Request Smuggling as part of its 12 security checks. The scanner tests the unauthenticated attack surface by sending requests with manipulated headers and analyzing how the server processes them. middleBrick provides a security risk score (A-F) with specific findings about smuggling vulnerabilities, including severity levels and remediation guidance. The scanner works without requiring access to your source code or credentials.