MEDIUM CWE-93 Input Validation

CWE-93 in APIs

CWE ID
CWE-93
Category
Input Validation
Severity
MEDIUM
Short Name
CRLF Injection

What is CWE-93?

CWE-93 refers to Improper Neutralization of CRLF Sequences ('CRLF Injection'). This weakness occurs when an application fails to neutralize carriage return and line feed characters in user-controlled data. Attackers can inject malicious CRLF sequences to manipulate the structure of data, often leading to HTTP response splitting, log injection, or header injection attacks.

The vulnerability arises because CRLF sequences ( ) are control characters that signify the end of a line in many protocols. When user input containing these sequences is not properly sanitized before being included in HTTP headers, logs, or other structured data, an attacker can insert additional headers, split responses, or inject arbitrary content.

CWE-93 in API Contexts

In API development, CWE-93 commonly manifests in several ways:

  • HTTP Header Injection: APIs that reflect user input in headers without sanitization can be manipulated to add new headers or split responses
  • Log Injection: APIs that log user input without proper escaping can have their logs manipulated, potentially hiding malicious activity or injecting false entries
  • CSV Injection: APIs generating CSV files that include user input without sanitization can be exploited for formula injection
  • WebSocket Messages: APIs using WebSockets that don't properly handle message framing can be vulnerable to message injection

Consider an API endpoint that logs user agent strings:

const logUserAgent = (req, res) => {
  const userAgent = req.headers['user-agent'];
  console.log(`User agent: ${userAgent}`);
  res.json({ message: 'Logged' });
};

If an attacker sends a user agent containing sequences, they can inject arbitrary log entries, potentially obscuring their actual activity.

Detection

Detecting CWE-93 requires both manual code review and automated scanning. Look for these patterns:

  • Direct inclusion of user input in HTTP headers without validation
  • Concatenation of user input into log messages
  • Reflection of user input in response headers
  • Generation of CSV or other structured files with unvalidated user input

middleBrick scans for CRLF injection vulnerabilities by testing API endpoints with specially crafted payloads containing sequences. The scanner attempts to inject CRLF sequences into parameters, headers, and request bodies to observe if the API is vulnerable to response splitting or header injection.

For example, middleBrick might test with payloads like:

name=Bob%0D%0ALocation:%20http://evil.com
Content-Type:%20text/html
%0D%0AHTTP/1.1%20200%20OK
%0D%0AContent-Type:%20text/html
%0D%0A
%0D%0A<script>alert('XSS')</script>

If the API reflects this payload in headers or responses without proper neutralization, it indicates a vulnerability.

middleBrick's black-box scanning approach tests the actual runtime behavior of your API without requiring source code access, making it effective for identifying CRLF injection in production environments.

Remediation

Fixing CWE-93 requires proper input validation and output encoding. Here are effective remediation strategies:

1. Input Validation

Validate and sanitize all user input before processing. Remove or encode CRLF sequences:

function sanitizeInput(input) {
  if (typeof input !== 'string') return input;
  return input.replace(/[
]+/g, '');
}

// Usage
const safeInput = sanitizeInput(req.query.name);

2. HTTP Header Construction

When constructing HTTP headers, use safe APIs that automatically handle encoding:

// Bad - vulnerable to injection
res.setHeader('X-User', userInput);

// Good - use safe methods
res.setHeader('X-User', encodeURIComponent(userInput));

3. Log Sanitization

Sanitize log entries to prevent injection:

function safeLog(message, data) {
  const sanitizedData = data.replace(/[
]/g, ' ');
  console.log(`${message}: ${sanitizedData}`);
}

4. CSV Generation

When generating CSV files, properly escape user input:

function escapeCSV(input) {
  if (input.includes(',') || input.includes('
') || input.includes('
') || input.includes('"')) {
    return '"' + input.replace(/"/g, '""') + '"';
  }
  return input;
}

// Usage
const csvRow = [escapeCSV(name), escapeCSV(email), escapeCSV(message)].join(',');

5. Framework-Specific Protections

Leverage framework protections when available:

// Express.js - use built-in escaping
app.set('json escape', true);

// FastAPI - use Pydantic models with validation
from fastapi import FastAPI
from pydantic import BaseModel

class SafeInput(BaseModel):
    name: str = Field(..., regex=r'^[^
]*$')

The key principle is to never trust user input and always validate or encode before including it in structured data formats.

Frequently Asked Questions

How does CWE-93 differ from other injection vulnerabilities like SQL injection?
CWE-93 specifically targets control characters (CRLF) that affect data structure, while SQL injection targets query syntax. CRLF injection manipulates protocol formatting (HTTP headers, logs, CSV), whereas SQL injection manipulates database query logic. Both require proper input validation, but the attack vectors and consequences differ significantly.
Can middleBrick detect CRLF injection in APIs that use GraphQL?
Yes, middleBrick tests GraphQL endpoints for CRLF injection by sending mutations and queries with CRLF payloads in variables, arguments, and headers. The scanner checks if the GraphQL server properly neutralizes these sequences in error messages, logs, or responses. This is particularly important as GraphQL APIs often have complex input structures that may inadvertently expose CRLF vulnerabilities.