CWE-113 in APIs
- CWE ID
- CWE-113
- Category
- Input Validation
- Severity
- MEDIUM
- Short Name
- Response Splitting
What is CWE-113
CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers ("HTTP Response Splitting") is a critical web application vulnerability where untrusted data is not properly neutralized before being included in HTTP headers. The weakness allows attackers to inject Carriage Return (CR) and Line Feed (LF) characters, enabling them to craft malicious HTTP responses that can manipulate browser behavior, perform session fixation, or conduct phishing attacks.
CWE-113 in API Contexts
In API development, CWE-113 manifests when API endpoints construct HTTP responses using untrusted input without proper sanitization. This commonly occurs in:
- Authorization headers built from user input
- Custom response headers reflecting user data
- Redirect URLs constructed from query parameters
- Error messages or debug information in headers
- API keys or tokens reflected in response headers
Consider an API that constructs a Location header for redirects using a user-supplied URL parameter. If an attacker provides a URL containing CRLF sequences, they can inject arbitrary headers or even start a new HTTP response entirely. This becomes particularly dangerous in APIs that serve as middleware or proxy services, where malicious headers might be forwarded to downstream services.
Detection
Detecting CWE-113 requires both manual code review and automated testing. Key detection strategies include:
- Static analysis to identify string concatenation operations that build HTTP headers
- Dynamic testing with payloads containing %0D%0A sequences to trigger CRLF injection
- Security scanning tools that specifically test for HTTP response splitting
- Input validation testing across all API endpoints that construct headers
middleBrick Detection: middleBrick's HTTP Response Splitting check specifically tests for CRLF injection vulnerabilities by injecting payloads containing %0D%0A sequences into HTTP headers. The scanner examines responses for signs of header injection, including unexpected headers, response splitting, or XSS payloads in reflected headers. For APIs with OpenAPI specifications, middleBrick cross-references parameter definitions with runtime testing to identify parameters that might be reflected in headers without proper validation.
Remediation
Fixing CWE-113 requires a defense-in-depth approach with proper input validation and output encoding. Here are practical remediation strategies with code examples:
1. Input Validation and Sanitization
// Vulnerable code
const url = req.query.redirectUrl;
res.setHeader('Location', url);
res.redirect(302);
// Secure implementation
function sanitizeUrl(input) {
const url = new URL(input);
// Validate scheme
const allowedSchemes = ['https', 'http'];
if (!allowedSchemes.includes(url.protocol.slice(0, -1))) {
throw new Error('Invalid URL scheme');
}
// Remove CRLF characters
if (input.includes('
') || input.includes('
')) {
throw new Error('CRLF injection detected');
}
return url.toString();
}
// Usage
const redirectUrl = sanitizeUrl(req.query.redirectUrl);
res.setHeader('Location', redirectUrl);
res.redirect(302);
2. Header Construction Best Practices
# Vulnerable code
response_headers = {
'X-Custom-Header': user_input,
'Content-Type': 'application/json'
}
# Secure implementation
from urllib.parse import urlparse
def build_secure_headers(user_input):
# Validate and sanitize user input
if '\r' in user_input or '\n' in user_input:
raise ValueError('CRLF characters detected')
# Additional validation based on header context
if 'X-Custom-Header' in header_name:
# Apply specific validation rules
if len(user_input) > 1000:
raise ValueError('Header value too long')
return user_input
# Usage
user_input = build_secure_headers(user_input)
response_headers = {
'X-Custom-Header': user_input,
'Content-Type': 'application/json'
}
3. Using Framework Security Features
// Spring Boot secure header handling
@RestController
@RequestMapping("/api")
public class SecureApiController {
@GetMapping("/redirect")
public ResponseEntity secureRedirect(@RequestParam String url) {
// Validate URL
try {
URI uri = new URI(url);
if (uri.getScheme() == null ||
(!uri.getScheme().equals("https") && !uri.getScheme().equals("http"))) {
throw new IllegalArgumentException("Invalid URL scheme");
}
// Check for CRLF injection
if (url.contains("\r") || url.contains("\n")) {
throw new IllegalArgumentException("CRLF injection detected");
}
return ResponseEntity.status(HttpStatus.FOUND)
.location(uri)
.build();
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid URL format");
}
}
}
4. Comprehensive Security Testing
# Test for CRLF injection using curl
curl -v "http://your-api.com/redirect?url=http://example.com%0D%0AX-Injected-Header: malicious-value"
# Expected: Server should reject or properly encode the input
# Actual: Server should not include the injected header in the response