HIGH crlf injectionrestify

Crlf Injection in Restify

How Crlf Injection Manifests in Restify

Crlf Injection (Carriage Return Line Feed Injection) in Restify applications occurs when untrusted input is used to construct HTTP headers, response bodies, or URLs without proper sanitization. Restify's middleware architecture and header handling create specific attack vectors that differ from other Node.js frameworks.

The most common Restify-specific manifestation involves the res.header() method and response manipulation. Consider this vulnerable pattern:

const restify = require('restify');

const server = restify.createServer();
server.use(restify.plugins.bodyParser());

server.post('/set-header', (req, res) => {
const headerName = req.body.name;
const headerValue = req.body.value;
res.header(headerName, headerValue);
res.send(200, { success: true });
});

An attacker could send:

{
"name": "X-Injected\r\nContent-Type",r> "value": "text/html\r\n\r\n<script>alert('XSS')</script>\r\n"
}

This would inject additional headers and potentially HTML content into the response, leading to header injection, XSS, or cache poisoning.

Restify's res.send() method is another critical point. When sending JSON responses with status codes, malicious CRLF sequences can break out of the JSON structure:

server.get('/vulnerable-json', (req, res) => {
const userData = req.query.user;
res.send(200, userData);
});

If userData contains CRLF sequences, an attacker might manipulate the HTTP response structure, potentially causing browsers to interpret parts of the response as new headers or HTML content.

Restify's res.redirect() method also presents risks when user input is incorporated into redirect URLs:

server.get('/redirect', (req, res) => {
const url = req.query.next || '/default';
res.redirect(302, url);
});

An attacker could inject CRLF sequences into the next parameter, potentially manipulating HTTP headers in the redirect response or causing open redirect vulnerabilities with header injection.

The res.cookie() method in Restify is particularly vulnerable when cookie values contain untrusted data:

server.get('/set-pref', (req, res) => {
const theme = req.query.theme || 'light';
res.cookie('theme', theme, { httpOnly: true });
res.send(200);
});

If theme contains CRLF sequences, an attacker could inject additional Set-Cookie headers or manipulate the HTTP response structure.

Restify-Specific Detection

Detecting CRLF Injection in Restify applications requires understanding both the framework's specific APIs and the attack patterns. middleBrick's black-box scanning approach is particularly effective for Restify applications because it tests the actual HTTP response behavior without requiring source code access.

When middleBrick scans a Restify endpoint, it sends payloads containing various CRLF injection patterns to each parameter and header. For a Restify application, the scanner specifically tests:

Header Injection Testing: middleBrick sends requests with header names and values containing %0D%0A sequences (URL-encoded CRLF) to test if the server interprets them as actual line breaks. For Restify's res.header() method, this reveals whether header injection is possible.

Response Body Manipulation: The scanner tests whether CRLF sequences in JSON responses or HTML content can break out of the expected response format. This is particularly relevant for Restify's res.send() method when handling user-supplied data.

Cookie Injection: middleBrick tests cookie values with embedded CRLF sequences to detect if Restify's res.cookie() method properly sanitizes input before setting HTTP headers.

Redirect Manipulation: The scanner tests redirect URLs for CRLF injection, which is critical for Restify applications using res.redirect() with user-supplied URLs.

For manual detection in Restify applications, you can use the following testing approach:

const testCRLFInjection = async (server) => {
const vulnerableEndpoints = [];

// Test header injection
const headerTest = await request(server)
.post('/set-header')
.send({
name: 'X-Test\r\nX-Injected',r> value: 'InjectedValue\r\nContent-Type: text/html'
});

if (headerTest.headers['x-injected']) {
vulnerableEndpoints.push('Header injection possible');
}

// Test response body injection
const bodyTest = await request(server)
.get('/vulnerable-json')
.query({ user: '{"data": "value\r\n\r\n<script>alert(1)</script>"}' });

if (bodyTest.text.includes('<script>')) {
vulnerableEndpoints.push('Response body injection possible');
}

return vulnerableEndpoints;
};

middleBrick's advantage is that it performs these tests automatically across all endpoints, providing a comprehensive security score and prioritized findings. The scanner's 12 security checks include specific validation for CRLF injection patterns, and it tests both authenticated and unauthenticated endpoints.

For Restify applications with OpenAPI specifications, middleBrick can cross-reference the spec definitions with runtime findings, providing even more accurate detection of CRLF injection vulnerabilities in API endpoints.

Restify-Specific Remediation

Remediating CRLF Injection in Restify applications requires a defense-in-depth approach using the framework's built-in capabilities and Node.js best practices. Here are Restify-specific remediation strategies:

Input Validation and Sanitization: Restify's req.query(), req.params(), and req.body() methods return user input that must be sanitized before use. Implement a middleware for CRLF sanitization:

const sanitizeCRLF = (input) => {
if (typeof input !== 'string') return input;
return input.replace(/\r\n/g, ' ').replace(/\n/g, ' ').replace(/\r/g, ' ');
};

const crlfSanitizer = (req, res, next) => {
// Sanitize query parameters
Object.keys(req.query).forEach(key => {
req.query[key] = sanitizeCRLF(req.query[key]);
});

// Sanitize URL parameters
Object.keys(req.params).forEach(key => {
req.params[key] = sanitizeCRLF(req.params[key]);
});

// Sanitize body (for JSON bodies)
if (req.body && typeof req.body === 'object') {
sanitizeObject(req.body);
}

next();
};

const sanitizeObject = (obj) => {
Object.keys(obj).forEach(key => {
if (typeof obj[key] === 'string') {
obj[key] = sanitizeCRLF(obj[key]);
} else if (typeof obj[key] === 'object') {
sanitizeObject(obj[key]);
}
});
};

Add this middleware early in your Restify application:

server.use(restify.plugins.bodyParser());
server.use(crlfSanitizer);

Header Construction Safety: When constructing headers dynamically, validate header names against a whitelist:

const validHeaders = new Set([
'content-type', 'x-custom-header', 'authorization', 'user-agent'
]);

server.post('/set-header', (req, res) => {
const headerName = sanitizeCRLF(req.body.name).toLowerCase();
const headerValue = sanitizeCRLF(req.body.value);

if (!validHeaders.has(headerName)) {
return res.send(400, { error: 'Invalid header name' });
}

res.header(headerName, headerValue);
res.send(200, { success: true });
});

Response Construction Safety: When sending user data in responses, ensure proper JSON serialization and avoid direct string interpolation:

server.get('/user-data', (req, res) => {
const userId = sanitizeCRLF(req.query.id);

// Always send objects, never strings
res.send(200, { data: userData });
});

Cookie Security: Sanitize cookie values and use Restify's built-in cookie options:

server.get('/set-pref', (req, res) => {
const theme = sanitizeCRLF(req.query.theme || 'light');

// Validate against allowed values
const allowedThemes = ['light', 'dark', 'auto'];
if (!allowedThemes.includes(theme)) {
return res.send(400, { error: 'Invalid theme' });
}

res.cookie('theme', theme, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
res.send(200);
});

Redirect Safety: Validate redirect URLs against a whitelist of allowed domains:

const allowedRedirectDomains = new Set([
'example.com', 'app.example.com', 'api.example.com'
]);

server.get('/redirect', (req, res) => {
const nextUrl = sanitizeCRLF(req.query.next);

try {
const url = new URL(nextUrl);
if (!allowedRedirectDomains.has(url.hostname)) {
return res.send(400, { error: 'Invalid redirect URL' });
}
res.redirect(302, nextUrl);
} catch (err) {
res.redirect(302, '/default');
}
});

Automated Testing: Integrate CRLF injection testing into your CI/CD pipeline using middleBrick's GitHub Action:

- name: Run middleBrick Security Scan
uses: middlebrick/middlebrick-action@v1
with:
api-url: ${{ secrets.API_URL }}
fail-on-severity: high
token: ${{ secrets.MIDDLEBRICK_TOKEN }}

This ensures that any CRLF injection vulnerabilities are caught before deployment. middleBrick's continuous monitoring in the Pro plan can also alert you if new vulnerabilities are introduced in production APIs.

Frequently Asked Questions

How does CRLF injection in Restify differ from other Node.js frameworks?
Restify's specific middleware architecture and header handling create unique attack vectors. The framework's res.header(), res.send(), and res.cookie() methods are particularly vulnerable when handling unsanitized user input. Restify also has specific response construction patterns that, if misused, can lead to CRLF injection. The framework's focus on API development means these vulnerabilities often manifest in HTTP header manipulation rather than HTML content injection.
Can middleBrick detect CRLF injection in Restify applications without source code access?
Yes, middleBrick's black-box scanning approach is ideal for Restify applications. The scanner sends payloads containing CRLF sequences to all endpoints and analyzes the actual HTTP responses for signs of injection. It tests header manipulation, response body construction, cookie setting, and redirect handling—all common Restify patterns where CRLF injection occurs. The scanner doesn't need access to your source code, making it perfect for testing production APIs or third-party services.