报告 #3516878 - 使用自定义Host头时的跨源Cookie泄漏与注入风险 | HackerOne
时间线
- 16 小时前:ichise 向 cURL 提交了一份报告。
摘要
当指定自定义主机名时,如果该传输的Cookie引擎也已启用,则该主机名将用于Cookie匹配。即使在跨源重定向中,原始提供的主机名已被移除,这种匹配行为依然持续。
技术细节
Cookiehost的设置
cookiehost 从自定义的Host头中设置: lib/http.c 文件中的 http_set_aptr_host 函数:
c
ptr = Curl_checkheaders(data, STRCONST("Host"));
if(ptr && (!data->state.this_is_a_follow || curl_strequal(data->state.first_host, conn->host.name))) {
/* 如果我们有一个给定的自定义 Host: 头,我们会提取主机名,
以便稍后可能用于Cookie相关的操作。只有在这不是重定向的情况下,我们才允许自定义 Host: 头,
因为在重定向请求中设置 Host: 是非常危险的操作。除非主机名与第一个相同! */
char *cookiehost;
CURLcode result = copy_custom_value(ptr, &cookiehost);
...
aptr->cookiehost = cookiehost;
}
Cookiehost的使用
cookiehost 同时用于发送Cookie和处理Set-Cookie:
在 lib/http.c 文件的 http_header_s 函数中:
c
v = (data->cookies && data->state.cookie_engine) ? HD_VAL(hd, hdlen, "Set-Cookie:") : NULL;
...
/* 如果存在自定义设置的 Host: 名称,则在此处使用它,否则使用真实的对方主机名。 */
const char *host = data->state.aptr.cookiehost ?
data->state.aptr.cookiehost : conn->host.name;
...
result = Curl_cookie_add(data, data->cookies, TRUE, FALSE, v, host,
data->state.up.path, secure_context);
在 lib/http.c 文件的 http_cookies 函数中:
c
const char *host = data->state.aptr.cookiehost ?
data->state.aptr.cookiehost : data->conn->host.name;
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
result = Curl_cookie_getlist(data, data->conn, &okay, host, &list);
问题根源 :由于 cookiehost 在重定向时未被清除,此行为会在跨源重定向中持续存在。
官方文档说明
libcurl 关于 CURLOPT_HTTPHEADER 的文档[1]提到:
erlang
指定的主机名用于Cookie匹配,如果此传输的Cookie引擎也已启用...
但没有明确警告此行为也适用于跨源重定向。
受影响版本
测试于 cURL 8.18.0。
复现步骤
bash
user@pc:~$ curl -v -L -c cookies.txt -H "Host: example.com" --resolve b.com:8001:127.0.0.1 --resolve a.com:8000:127.0.0.1 a.com:8000
* 添加 b.com:8001:127.0.0.1 到 DNS 缓存
* 添加 a.com:8000:127.0.0.1 到 DNS 缓存
* 在 DNS 缓存中找到主机名 a.com
* 正在尝试 127.0.0.1:8000...
* 已建立连接到 a.com (127.0.0.1 端口 8000),源地址 127.0.0.1 端口 56874
* 使用 HTTP/1.x
> GET / HTTP/1.1
> Host: example.com
> User-Agent: curl/8.18.0
> Accept: */*
>
* 请求已完全发送
* HTTP 1.0,假设在正文后关闭连接
< HTTP/1.0 302 Found
< Server: BaseHTTP/0.6 Python/3.12.3
< Date: Mon, 19 Jan 2026 12:35:05 GMT
< Location: http://b.com:8001/
* 为域 example.com、路径 /、过期时间 0 添加 Cookie ccc="secret"
< Set-Cookie: ccc=secret; Path=/
< Content-Length: 0
<
* 正在关闭连接 #0
* 清除认证信息,从端口 8000 重定向到 8001
* 向此 URL 发出另一个请求:'http://b.com:8001/'
* 在 DNS 缓存中找到主机名 b.com
* 正在尝试 127.0.0.1:8001...
* 已建立连接到 b.com (127.0.0.1 端口 8001),源地址 127.0.0.1 端口 43966
* 使用 HTTP/1.x
> GET / HTTP/1.0
> Host: b.com:8001
> User-Agent: curl/8.18.0
> Accept: */*
> Cookie: ccc=secret
>
* 请求已完全发送
* HTTP 1.0,假设在正文后关闭连接
< HTTP/1.0 302 Found
< Server: BaseHTTP/0.6 Python/3.12.3
< Date: Mon, 19 Jan 2026 12:35:05 GMT
* 为域 example.com、路径 /、过期时间 0 添加 Cookie bbb="test"
< Set-Cookie: bbb=test; Path=/
< Location: http://a.com:8000/check
< Content-Length: 0
<
* 正在关闭连接 #1
* 清除认证信息,从端口 8001 重定向到 8000
* 向此 URL 发出另一个请求:'http://a.com:8000/check'
* 在 DNS 缓存中找到主机名 a.com
* 正在尝试 127.0.0.1:8000...
* 已建立连接到 a.com (127.0.0.1 端口 8000),源地址 127.0.0.1 端口 56882
* 使用 HTTP/1.x
> GET /check HTTP/1.0
> Host: example.com
> User-Agent: curl/8.18.0
> Accept: */*
> Cookie: bbb=test; ccc=secret
>
* 请求已完全发送
* HTTP 1.0,假设在正文后关闭连接
< HTTP/1.0 200 OK
< Server: BaseHTTP/0.6 Python/3.12.3
< Date: Mon, 19 Jan 2026 12:35:05 GMT
< Content-Length: 0
<
* 正在关闭连接 #2
查看生成的Cookie文件:
bash
user@pc:~$ cat cookies.txt
# Netscape HTTP Cookie File
# https://curl.se/docs/http-cookies.html
# 此文件由 libcurl 生成!请自行承担编辑风险。
example.com FALSE / FALSE 0 bbb test
example.com FALSE / FALSE 0 ccc secret
参考文献
1\] [curl.se/libcurl/c/C...](https://link.juejin.cn?target=https%3A%2F%2Fcurl.se%2Flibcurl%2Fc%2FCURLOPT_HTTPHEADER.html "https://curl.se/libcurl/c/CURLOPT_HTTPHEADER.html") ### 影响 跨源Cookie泄漏和注入风险。 ### 项目方回复 * **15 小时前** :`bagder` (cURL 员工) 发表评论:"这是预期的行为。" * **13 小时前** :`bagder` 关闭了报告并将状态更改为"不适用",并补充道:"欢迎建议改进文档的措辞以使其更清晰,但我们确实尝试记录这一点,并且任何实际尝试和测试此功能的应用程序都会看到它。这不是一个安全问题。" * **13 小时前** :`bagder` 请求公开此报告:"根据项目的透明度政策,我们希望所有报告都被公开。" * **4 小时前** :`bagder` 公开了此报告。 ### 报告信息 * **报告时间**:2026年1月19日,下午6:46 (UTC) * **报告者**:ichise * **报告对象**:curl * **报告 ID**:#3516878 * **严重等级**:未评级 (---) * **公开时间**:2026年1月20日,上午6:48 (UTC) * **弱点**:凭证保护不足 * **CVE ID**:无 * **赏金**:无FINISHED biOK/hzhVF2yKaGc5mK8oeejIYuUYW8I3RsXQCFCiXX2FBas+esuFymsr4+a87Du