CRLF Injection in Symfony: Fix & Examples

CRLF Injection in Symfony — What It Is & How to Fix It

Carriage Return + Line Feed (CR + LF) lets attackers smuggle new HTTP headers or split responses if user input is reflected into headers. In Symfony, this often happens when building Content-Disposition, Location, or custom headers from request data.

CRLF Injection in Symfony: Fix & Examples

A Tiny Vulnerable Controller

// src/Controller/DownloadController.php
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

public function download(Request $r): Response {
    $name = $r->query->get('file'); // e.g., a.pdf%0D%0ASet-Cookie:%20crlf=1
    return new Response('OK', 200, [
        'Content-Disposition' => "attachment; filename=\"$name\""
    ]);
}

Proof-of-Concept Request

GET /download?file=a.pdf%0D%0ASet-Cookie:%20crlf=1 HTTP/1.1
Host: example.com

If unprotected, the server may emit an injected Set-Cookie header.


Safer Header Construction (Quick Fix)

$name = $r->query->get('file', '');
$safe = preg_replace("/[\r\n]/", '', $name); // strip CR/LF
$response = new Response('OK');
$response->headers->set('Content-Disposition', "attachment; filename=\"$safe\"");
return $response;

Best Practice with Symfony’s ResponseHeaderBag

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;

$name = $r->query->get('file', 'download.txt');
$name = preg_replace("/[\r\n]/", '', $name);

$response = new Response('OK');
$disposition = $response->headers->makeDisposition(
    ResponseHeaderBag::DISPOSITION_ATTACHMENT,
    $name,
    'download.txt' // safe fallback
);
$response->headers->set('Content-Disposition', $disposition);
return $response;

Redirects & Headers

Never pipe raw input into Location or custom headers.

// BAD
$response->headers->set('Location', $r->query->get('next'));

// GOOD
return $this->redirectToRoute('file_show', ['name' => $safe]);

Quick Tester (CLI)

curl -i "https://your-app/download?file=a%0D%0ASet-Cookie:%20crlf=1"

If you see an unexpected header, you likely have CRLF injection.


Screenshot of our free Website Vulnerability Scanner:

Screenshot of the free tools webpage where you can access security assessment tools.
Screenshot of the free tools webpage where you can access security assessment tools.

Defense-in-Depth Checklist

  • Strip \r and \n from any value that may reach headers.

  • Use framework APIs (ResponseHeaderBag::makeDisposition).

  • Prefer IDs over raw names in URLs; map to a safe filename server-side.

  • Add centralized sanitizer (kernel event listener) for header-bound values.

  • Test continuously in CI with PoC payloads.

Sample assessment report generated by our free tool to check Website Vulnerability:

Sample vulnerability assessment report generated with our free tool, providing insights into possible vulnerabilities.
Sample vulnerability assessment report generated with our free tool, providing insights into possible vulnerabilities.

Keep Learning

Read more security articles: https://www.pentesttesting.com/blog/


Related Services (Pentest Testing Corp.)

Managed IT Services

Harden endpoints, patch pipelines, and monitoring:
https://www.pentesttesting.com/managed-it-services/

AI Application Cybersecurity

Threat-model and test LLM/AI features safely:
https://www.pentesttesting.com/ai-application-cybersecurity/

Offer Cybersecurity to Your Clients

White-label pentesting/assessments for agencies:
https://www.pentesttesting.com/offer-cybersecurity-service-to-your-client/


Newsletter

Subscribe on LinkedIn https://www.linkedin.com/build-relation/newsletter-follow?entityUrn=7327563980778995713

Comments

Popular posts from this blog

Fix Sensitive Data Exposure in Symfony Apps

Fix Security Misconfiguration Issues in Symfony

Open Redirect Vulnerability in Symfony