HIGH crlf injectionlaravel

Crlf Injection in Laravel

How Crlf Injection Manifests in Laravel

CRLF injection in Laravel applications typically occurs when user-controlled data is included in HTTP headers without proper sanitization. The attack exploits the fact that HTTP headers are separated by CRLF (Carriage Return Line Feed, or \r\n) sequences, allowing attackers to inject additional headers or modify existing ones.

In Laravel, common vulnerability points include:

  • Redirect responses with user-controlled URLs in redirect()->away() or redirect()->to()
  • Response headers manipulated via header() or withHeaders()
  • Set-Cookie headers with unvalidated user input
  • Email headers in Laravel's Mail facade when using raw headers

Here's a vulnerable Laravel code example:

// Vulnerable: User input in Location header
public function redirectWithParam(Request $request) {
    $url = $request->input('redirect_url');
    return redirect()->away($url);
}

// Vulnerable: Header injection via user input
public function setCustomHeader(Request $request) {
    $headerName = $request->input('header_name');
    $headerValue = $request->input('header_value');
    return response('OK')
        ->withHeaders([$headerName => $headerValue]);
}

// Vulnerable: Email header injection
public function sendEmail(Request $request) {
    $email = $request->input('email');
    $subject = $request->input('subject');
    $message = $request->input('message');
    
    Mail::raw("Subject: {$subject}\n\n{$message}", function ($message) use ($email) {
        $message->to($email);
    });
}

An attacker could exploit these by sending requests with encoded CRLF sequences:

# HTTP header injection
curl -X GET "http://example.com/redirect?redirect_url=http://evil.com%0d%0aSet-Cookie:%20session=evil"

This would inject a malicious Set-Cookie header into the response, potentially hijacking user sessions.

Laravel-Specific Detection

Detecting CRLF injection in Laravel requires both manual code review and automated scanning. Key detection strategies include:

  1. Static Analysis: Search for header-related methods and user input concatenation
  2. Dynamic Testing: Send requests with encoded CRLF sequences and observe responses
  3. Automated Scanning: Use specialized tools that understand Laravel's patterns

Manual detection checklist for Laravel:

// Search for these patterns in your codebase:
// 1. redirect()->away() with user input
// 2. redirect()->to() with user input
// 3. withHeaders() calls
// 4. header() function usage
// 5. Mail::raw() with user input in headers
// 6. Response::header() calls

// Look for these dangerous patterns:
$userInput . "\r\n" // direct concatenation
urlencode($userInput) // improper encoding
base64_decode($userInput) // decoding without validation

middleBrick offers specialized detection for Laravel applications through its automated scanning platform. The scanner identifies CRLF injection vulnerabilities by:

  • Testing header injection points with encoded CRLF sequences
  • Analyzing Laravel-specific response patterns and redirect methods
  • Checking email functionality for header injection
  • Providing Laravel-specific remediation guidance based on the detected vulnerability

To scan a Laravel API with middleBrick:

# Using the CLI tool
middlebrick scan https://your-laravel-app.com/api

# Using the GitHub Action
- name: Scan Laravel API
  uses: middlebrick/middlebrick-action@v1
  with:
    api_url: 'https://your-laravel-app.com/api'
    fail_threshold: 'C'

The scanner tests for CRLF injection by sending payloads like:

%0d%0aSet-Cookie:%20session=malicious
%0d%0aContent-Length:%200%0d%0aX-Injected-Header:%20value

and analyzes the responses for successful header injection.

Laravel-Specific Remediation

Remediating CRLF injection in Laravel involves input validation, proper encoding, and using Laravel's built-in security features. Here are specific fixes for common vulnerability patterns:

1. Secure Redirects

// Vulnerable
public function redirectWithParam(Request $request) {
    $url = $request->input('redirect_url');
    return redirect()->away($url);
}

// Secure
public function redirectWithParam(Request $request) {
    $url = $request->input('redirect_url');
    
    // Validate URL scheme and host
    if (!filter_var($url, FILTER_VALIDATE_URL) || 
        !in_array(parse_url($url, PHP_URL_SCHEME), ['http', 'https'])) {
        abort(400, 'Invalid redirect URL');
    }
    
    return redirect()->away($url);
}

// Alternative: Whitelist allowed URLs
public function redirectWithParam(Request $request) {
    $url = $request->input('redirect_url');
    $allowedHosts = ['example.com', 'app.example.com'];
    
    $parsedUrl = parse_url($url);
    if (!$parsedUrl || !in_array($parsedUrl['host'], $allowedHosts)) {
        abort(400, 'Invalid redirect URL');
    }
    
    return redirect()->away($url);
}

2. Safe Header Manipulation

// Vulnerable
public function setCustomHeader(Request $request) {
    $headerName = $request->input('header_name');
    $headerValue = $request->input('header_value');
    return response('OK')
        ->withHeaders([$headerName => $headerValue]);
}

// Secure
public function setCustomHeader(Request $request) {
    $headerName = $request->input('header_name');
    $headerValue = $request->input('header_value');
    
    // Validate header name
    $allowedHeaders = ['X-Custom-Header', 'X-Request-ID'];
    if (!in_array($headerName, $allowedHeaders)) {
        abort(400, 'Invalid header name');
    }
    
    // Sanitize header value (remove CRLF)
    $sanitizedValue = preg_replace('/[
]+/', '', $headerValue);
    
    return response('OK')
        ->header($headerName, $sanitizedValue);
}

3. Secure Email Headers

// Vulnerable
public function sendEmail(Request $request) {
    $email = $request->input('email');
    $subject = $request->input('subject');
    $message = $request->input('message');
    
    Mail::raw("Subject: {$subject}\n\n{$message}", function ($message) use ($email) {
        $message->to($email);
    });
}

// Secure
public function sendEmail(Request $request) {
    $email = $request->input('email');
    $subject = $request->input('subject');
    $message = $request->input('message');
    
    // Validate email format
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        abort(400, 'Invalid email address');
    }
    
    // Sanitize subject (remove CRLF)
    $sanitizedSubject = preg_replace('/[
]+/', ' ', $subject);
    
    // Use Laravel's proper mail methods instead of raw
    Mail::raw($message, function ($m) use ($email, $sanitizedSubject) {
        $m->to($email)
          ->subject($sanitizedSubject);
    });
}

4. Middleware for Global Protection

// Create a middleware to sanitize headers globally
php artisan make:middleware CrlfProtectionMiddleware

// app/Http/Middleware/CrlfProtectionMiddleware.php
public function handle($request, Closure $next) {
    $response = $next($request);
    
    // Sanitize all headers in the response
    foreach ($response->headers->all() as $name => $values) {
        $sanitizedValues = array_map(function($value) {
            return preg_replace('/[
]+/', '', $value);
        }, $values);
        $response->headers->set($name, $sanitizedValues);
    }
    
    return $response;
}

// Register in app/Http/Kernel.php
protected $middleware = [
    // ... other middleware
    \App\Http\Middleware\CrlfProtectionMiddleware::class,
];

Frequently Asked Questions

How does CRLF injection differ from other injection attacks in Laravel?
CRLF injection specifically targets HTTP headers by exploiting line breaks, while other injection attacks target different contexts (SQL injection for databases, XSS for HTML, etc.). In Laravel, CRLF injection often occurs through response headers and redirects, making it distinct from typical Laravel vulnerabilities like mass assignment or CSRF. The key difference is that CRLF injection manipulates the HTTP protocol structure itself, potentially allowing attackers to inject arbitrary headers like Set-Cookie or Location.
Can middleBrick detect CRLF injection in my Laravel application?
Yes, middleBrick's automated scanner specifically tests for CRLF injection vulnerabilities in Laravel applications. It sends encoded CRLF sequences to test endpoints and analyzes responses for successful header injection. The scanner understands Laravel's response patterns and redirect methods, providing Laravel-specific findings with severity levels and remediation guidance. You can scan your Laravel API using the CLI tool or integrate middleBrick into your CI/CD pipeline with the GitHub Action to catch CRLF injection issues before deployment.