Security Vulnerability Report: Protocol Injection via Programmatic Options
Unknown
Vulnerability Details
## Summary
Multiple text-based protocol handlers in `libcurl` (including FTP, SMTP, POP3, and IMAP) are vulnerable to protocol command injection. This occurs when an application sets credentials or other protocol-specific options programmatically (e.g., via `CURLOPT_USERNAME`, `CURLOPT_PASSWORD`, or `CURLOPT_MAIL_FROM`) using strings that contain CRLF (`\r\n`) sequences. These unsanitized inputs are passed directly to the protocol state machines and sent over the wire, allowing an attacker to inject arbitrary protocol commands.
## Affected Protocols
- **FTP**: Injection via `USER` and `PASS` commands.
- **SMTP**: Injection via `MAIL FROM`, `RCPT TO`, and SASL authentication tokens.
- **POP3**: Injection via `USER` and `PASS` commands.
- **IMAP**: Injection via `LOGIN` command (improper quoting of CRLF).
## Root Cause Analysis
The vulnerability stems from a lack of centralized sanitization for programmatic string options in [lib/setopt.c](file:///d:/curl/lib/setopt.c) and a corresponding lack of final-stage sanitization in the low-level [Curl_pp_sendf](file:///d:/curl/lib/pingpong.c#200-223) function in [lib/pingpong.c](file:///d:/curl/lib/pingpong.c).
While [curl](file:///d:/curl/lib/urlapi.c#1287-1293) implements robust sanitization for credentials provided via **URLs** (using `REJECT_CTRL` in `Curl_urldecode`) and **.netrc** files (using [str_has_ctrl](file:///d:/curl/lib/url.c#2452-2464) in [override_login](file:///d:/curl/lib/url.c#2470-2592)), these checks are bypassed when options are set programmatically.
### Vulnerable Code Path (Example: FTP)
1. **Input**: Application calls [curl_easy_setopt(curl, CURLOPT_USERNAME, "user\r\nINJECTED_COMMAND")](file:///d:/curl/lib/setopt.c#2915-2933).
2. **Storage**: [lib/setopt.c](file:///d:/curl/lib/setopt.c) stores the string without validation.
3. **Transfer**: [lib/transfer.c](file:///d:/curl/lib/transfer.c) copies the string to the internal connection structure.
4. **Protocol Execution**: [lib/ftp.c](file:///d:/curl/lib/ftp.c) calls [ftp_state_user()](file:///d:/curl/lib/ftp.c#741-753):
```c
/* lib/ftp.c:3547 */
result = Curl_pp_sendf(data, &ftpc->pp, "USER %s", ftp->user);
```
5. **Transmission**: [lib/pingpong.c](file:///d:/curl/lib/pingpong.c)'s [Curl_pp_sendf](file:///d:/curl/lib/pingpong.c#200-223) appends a final `\r\n` and sends the data:
```
USER user
INJECTED_COMMAND
\r\n
```
## Proof of Concept
A simple C program demonstrates the injection by setting a malicious username:
```c
#include <curl/curl.h>
int main(void) {
CURL *curl = curl_easy_init();
if(curl) {
/* Injecting a second USER command or any other protocol command */
curl_easy_setopt(curl, CURLOPT_URL, "ftp://127.0.0.1:2121/");
curl_easy_setopt(curl, CURLOPT_USERNAME, "user\r\nINJECTED_COMMAND");
curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
return 0;
}
```
## Remediation
1. **Centralized Sanitization**: Implement a [str_has_ctrl](file:///d:/curl/lib/url.c#2452-2464) check in [lib/setopt.c](file:///d:/curl/lib/setopt.c) for all string options that are used in text-based protocol commands, unless the protocol explicitly allows control characters (marked by `PROTOPT_USERPWDCTRL`).
2. **Protocol-Level Defense**: Enhance [Curl_pp_sendf](file:///d:/curl/lib/pingpong.c#200-223) to detect and reject (or safely escape) internal CRLF sequences in formatted commands.
3. **Consistent Validation**: Ensure that `CURLOPT_USERNAME`, `CURLOPT_PASSWORD`, and protocol-specific options like `CURLOPT_MAIL_FROM` are validated against the same standards as URL-based credentials.
## Impact
An attacker who can influence the strings passed to [curl_easy_setopt](file:///d:/curl/lib/setopt.c#2915-2933) in a `libcurl`-based application can:
- Bypass authentication by injecting subsequent commands.
- Perform unauthorized actions (e.g., deleting files via FTP, sending spoofed emails via SMTP).
- Exfiltrate data by redirecting protocol flows.
Actions
View on HackerOneReport Stats
- Report ID: 3627638
- State: Closed
- Substate: not-applicable