Loading HuntDB...

CRLF Injection in `--proxy-header` allows extra HTTP headers (CWE-93)

None
C
curl
Submitted None
Reported by oblivionsage

Vulnerability Details

Technical details and impact analysis

CRLF Injection
Hello Team, There is a bug in `curl` where a user can inject **new HTTP headers** into a proxy request by using special characters in the `--proxy-header` option. This is done by adding `\r\n` (carriage return + line feed) inside the header value. This breaks the HTTP format and lets the user create more headers from a single line # What’s the Problem? The problem happens because `curl` **does not check** for `\r` or `\n` in the input. So if a user puts: ```bash --proxy-header $'X-Test: hello\r\nX-Evil: owned' ``` The proxy sees **two headers**: ``` X-Test: hello X-Evil: owned ``` This is **not supposed to happen** # How the Code Works (with file paths and lines) Here’s how `curl` processes the `--proxy-header` input: ## Main Function `src/tool_main.c` line 238 Entry point of the program: ```c int main(int argc, char *argv[]) ``` ## Calling `operate()` `src/tool_main.c` line 284 ``` result = operate(&global, argc, argv); ``` ##CLI Parsing `src/tool_operate.c`, line 3186 ``` parse_args(global, argc, argv); ``` ##Handling `--proxy-header` `src/tool_getparam.c` line 2766 ```c case C_PROXY_HEADER: err = parse_header(global, config, cmd, nextarg); ``` ##Passing the value `src/tool_getparam.c`, line 1281 ``` err = add2list(&config->proxyheaders, nextarg); ``` ##No Filtering Happens `src/tool_paramhlp.c`, line 614–615 ``` ParameterError add2list(...) { struct curl_slist *newlist = curl_slist_append(*list, ptr); ``` At this point, the raw input (even if it includes \r\n) is passed as-is to `curl_slist_append()`, and then into the final HTTP request There is no check to block newline injection # Proof of Concept # 1. Start a fake proxy listener: ```bash nc -lvp 8080 ``` # 2. Run curl with a payload header: ```bash curl --proxy http://127.0.0.1:8080 \ --proxy-header $'X-Evil: val\r\nInjected-Header: pwned' \ http://example.com ``` Attachment: {F4325956} # 3. Netcat output: ``` Listening on 0.0.0.0 8080 Connection received on localhost 54198 GET http://example.com/ HTTP/1.1 Host: example.com User-Agent: curl/8.13.0 Accept: */* Proxy-Connection: Keep-Alive X-Evil: val Injected-Header: pwned ``` It proves that one CLI input caused **two** headers Attachment: {F4325954} ## Suggested Fix In this file: `src/tool_paramhlp.c`, inside `add2list()`, around line **615**: Add a simple check: ```c if(strchr(ptr, '\r') || strchr(ptr, '\n')) return PARAM_INVALID_HEADER; ``` This will block all `\r` or `\n` inside header input. ## Impact This bug allows the user to inject raw HTTP headers into proxy requests. By using a single command-line input, a user can add multiple headers.This breaks the normal HTTP format and can be used to: Bypass security filters (WAF, proxy rules) Inject spoofed headers like X-Forwarded-For, Authorization Poison logs on the proxy Bug is easy to test The issue is real and affects live network traffic Similar bugs in other tools got CVEs Tested on `curl 8.13.0` (May 2025), on Kali Linux Thanks for reviewing. Let me know if you need help verifying the fix

Report Details

Additional information and metadata

State

Closed

Substate

Not-Applicable

Submitted

Weakness

CRLF Injection