跳转到内容
← 返回系统剖析
系统剖析当代30 分钟阅读

curl:一个人维护的全球基础设施

curl — Global Infrastructure Maintained by One Person

手边任何一台联网设备,多半正在用 curl 说话。手机应用拉一张图、机顶盒检查固件更新、车机后台下载地图、打印机去查耗材余量、游戏主机同步存档——这些请求里有相当一部分不是应用自己写的网络代码,而是一个叫 libcurl 的 C 库替它们发出去的。curl 项目在 2025 年给出的估算是:全球约三百亿份装机。 这个数…

开源维护网络传输库向后兼容漏洞披露关键基础设施

手边任何一台联网设备,多半正在用 curl 说话。手机应用拉一张图、机顶盒检查固件更新、车机后台下载地图、打印机去查耗材余量、游戏主机同步存档——这些请求里有相当一部分不是应用自己写的网络代码,而是一个叫 libcurl 的 C 库替它们发出去的。curl 项目在 2025 年给出的估算是:全球约三百亿份装机。

这个数字没有权威审计,也不可能有,因为没有人有资格统计。它来自一种笨办法:curl 的许可证要求分发者保留版权声明,于是车机"开源许可"菜单里那行不起眼的 curl 成了唯一的统计线索。2025 年 8 月,丹尼尔·斯滕伯格(Daniel Stenberg)按这个办法数出了 47 个已确认在车上跑 curl 的汽车品牌——从丰田、大众、福特到特斯拉、保时捷、劳斯莱斯——并据此估计"几亿辆车"。七年前同样的数法只能数到一亿辆。

而在 curl 的 git 仓库里,总计约 39,000 次提交中,署名斯滕伯格的有 20,548 次,超过一半;排在第二位的贡献者是 3,262 次。项目发布列表的第一行是 1996 年 11 月 11 日的 0.1 版(当时它还叫 httpget,1998 年 3 月才改名 curl),最新一行是 2026 年 6 月 24 日的 8.21.0,中间是 275 个正式发布,几乎每一个都是同一个瑞典人按下的发布键。

这条线索和 xz 后门 构成一组。xz 展示的是"维护者的意愿被攻击"——三年的社会工程逼出一次维护权移交;curl 展示的是更常见的那一半:意愿被消耗。没有攻击者,只有报告、问卷、评分争议和永不结束的兼容承诺。

破除误解

误解一:curl 就是那个在终端里敲的下载命令。

命令行工具只是薄薄一层壳。在当前源码树里,src/ 目录(命令行工具)约 2.3 万行 C 代码,lib/ 目录(libcurl)约 17.6 万行。被装进汽车、电视、路由器、游戏机的从来不是那个命令,而是这个库——它没有界面、没有进程、没有名字出现在任务管理器里,只是被应用链接进去,然后代替应用去连网。你在终端里敲的 curl,本质上是 libcurl 的一个演示客户端,只不过这个演示客户端自己也成了事实标准。

误解二:"一个人维护"是修辞夸张,斯滕伯格自己也否认。

他确实否认过。2026 年 7 月,curl 的第 1,500 位提交作者出现时,他写道自己"早就不是 curl 的单人维护者了,现在连一半的提交都不到"。两件事同时为真,而这恰恰是问题所在:广度靠很多人,纵深靠一个人。 1,500 位提交作者里绝大多数只留下过一两个补丁;docs/THANKS 里三千七百多个名字大部分是报过一次 bug 的人。真正持续在场的,是一个不到十人的核心圈,而其中一人的历史提交量是第二名的六倍。这种形态比"只有一个人"更值得担心——它看上去人手充足,健康度指标全绿,直到你去问"谁来做下一个八周发布、谁来读下一封安全邮件"。

误解三:curl 这种量级的项目,背后总有个基金会或公司托底。

没有。curl 的治理文档第一句就是:没有法律实体("There is no legal entity")。项目不隶属任何伞形组织,不注册在任何国家,代码版权归各个作者自己所有,捐款由 Open Collective 这个美国非营利组织代持。斯滕伯格的工资来自 wolfSSL——一家卖 curl 商业支持的公司——但那是他个人与一家公司的雇佣关系,不是项目的制度保障。如果他明天离职,curl 的许可证、版本号、发布节奏一个字都不会变,改变的只是有没有人去做。

libcurl 的形状:一张 scheme 表和一组函数指针

libcurl 支持二十七种传输协议:dictfileftpftpsgophergophershttphttpsimapimapsldapldapsmqttmqttspop3pop3srtspscpsftpsmbsmbssmtpsmtpstelnettftpwswss。加上五个 SOCKS 代理 scheme,源码里一共登记 32 条 scheme 记录。

这些协议之间几乎没有共同点。HTTP 是一次请求一次响应;FTP 要开两条 TCP 连接,一条发命令、一条传数据;SMTP 和 IMAP 是多轮对话式的命令交换;TELNET 根本没有"传输结束"的概念;file: 甚至不碰网络。把它们塞进同一个 API,靠的是两层结构。

第一层是 scheme 表——一条 URL 前缀对应的全部静态属性:

c
struct Curl_scheme {
  const char *name;                /* 小写的 URL scheme 名 */
  const struct Curl_protocol *run; /* 实现,可为空 */
  curl_prot_t protocol;            /* CURLPROTO_* 里的单个位 */
  curl_prot_t family;              /* 协议族:ftps 的族是 ftp */
  uint32_t flags;                  /* PROTOPT_* 特性位 */
  uint16_t defport;                /* 默认端口 */
};
```

flags 那一栏是这套抽象的关节。PROTOPT_SSL 说明这个 scheme 自带 TLS,PROTOPT_DUAL 说明它要用两条连接(FTP 专属),PROTOPT_NONETWORK 说明它压根不上网(file: 专属),PROTOPT_NEEDSPWD 说明没设密码时要给个默认值,PROTOPT_CONN_REUSE 说明它的连接可以复用。整套 PROTOPT_* 现在有二十来个位。通用逻辑不需要知道自己在跑哪个协议,只需要读这些位。

第二层是 struct Curl_protocol,一张函数指针表——面向对象在 C 里的标准写法:

c
struct Curl_protocol {
  CURLcode (*setup_connection)(...);  /* 连接归属确定前的准备 */
  CURLcode (*do_it)(...);             /* 发出请求(必须实现) */
  CURLcode (*done)(...);              /* 收尾(必须实现) */
  CURLcode (*do_more)(...);           /* 请求的"第二段",为 FTP 而生 */
  CURLcode (*connect_it)(...);        /* 协议层握手 */
  CURLcode (*connecting)(...);        /* 握手未完成时反复调用 */
  CURLcode (*doing)(...);
  CURLcode (*proto_pollset)(...);     /* 告诉事件循环该等哪些 fd */
  CURLcode (*disconnect)(...);
  CURLcode (*write_resp)(...);        /* 协议特有的响应写出处理 */
  CURLcode (*follow)(...);            /* 该不该跟这个重定向 */
};
```

只有 do_itdone 是强制的,其余全部可空——空就走通用默认路径。TFTP 只填三四个格子,HTTP 填满大半。

取舍很清楚。 得到的是:一份连接复用池、一份代理支持、一份 TLS 抽象、一份超时与进度回调、一份 cookie 与认证实现,被二十七种协议共享;给 libcurl 加一个新协议,工作量是填一张表,而不是重写一个客户端。付出的是:这个骨架被最古怪的成员拉扯成了它现在的样子。do_more 这个函数存在的唯一理由,是 FTP 在发完 PASV/PORT 之后还要再建一条数据连接——对 HTTP 来说它永远是空指针,但每个读代码的人都得先理解它。抽象的形状由最难塞进去的那个成员决定,而不是由最常用的那个。

失效场景也很清楚:这套抽象假设"协议跑在一条字节流上,字节流下面是 socket"。HTTP/3 不成立——QUIC 把传输、加密、多路复用揉进了 UDP,没有那条流。这正是下一节的由来。

连接过滤器:迟到二十四年的一层抽象

2022 年的 curl 7.87.0 引入了"连接过滤器"(connection filters),主要作者是斯特凡·艾辛(Stefan Eissing,仓库里第六多产的提交者)。这是 curl 内部结构最大的一次改动,公开 API 一个字没变。

想法很简单:把"读、写、等事件、连接、关闭"这五个动作定义成一个统一接口,然后允许实现互相堆叠。每个过滤器只知道自己和下一层,不知道整条链长什么样。

直连:
  http://localhost/   conn -> cf-socket
  https://curl.se/    conn -> cf-ssl -> cf-socket
经 HTTP 代理隧道:
  https://curl.se/    conn -> cf-ssl -> cf-http-proxy -> cf-socket
经 HTTPS 代理隧道:
  https://curl.se/    conn -> cf-ssl -> cf-http-proxy -> cf-ssl -> cf-socket
经 SOCKS 再经 HTTP 代理:
  http://localhost/   conn -> cf-http-proxy -> cf-socks -> cf-socket
```

注意倒数第二行有两个 cf-ssl:与 HTTPS 代理之间一层 TLS,隧道内部到目标服务器又一层 TLS。在过滤器出现之前,这种嵌套是靠散落在各处的 if 判断拼出来的;有了过滤器,它只是同一个组件被压了两次。HTTP/2 的多路复用、HTTP/3 的 QUIC、Happy Eyeballs 的 IPv4/IPv6 并行拨号,现在都是链条上的一环。

为什么等了二十四年? 因为前二十年不需要。1998 年的 curl 只有 socket 和 SSL 两层,一个 if 就够了。代理、SOCKS、HTTP/2、QUIC、双栈并行是一个一个加上去的,每次加的时候单看都是小改动。抽象的收益只有在组合爆炸之后才大于成本——这也解释了为什么它没能在 xz 那样的项目里早早发生:重构抽象层需要一个既懂全局又有大块时间的人,而这恰好是单人维护项目最缺的东西。 curl 拿到这层抽象,是因为它在 2022 年已经有了第二个愿意长期投入的核心开发者。

代价是真实的:多一层间接调用,栈更深,出问题时要一层层往下追;调试网络问题从"看 socket"变成"看链条上哪一环没吐字节"。

两套 API:为什么 easy 接口二十五年不能改

libcurl 对外有两套并行接口。

easy 接口是四个函数的直线:curl_easy_init() 拿句柄,curl_easy_setopt() 设一堆选项,curl_easy_perform() 阻塞着把整个传输跑完,curl_easy_cleanup() 收工。绝大多数使用 libcurl 的程序只用这四个。

multi 接口把同一件事拆成非阻塞的步进:curl_multi_add_handle() 把若干个 easy 句柄挂进一个 multi 句柄,然后应用自己跑事件循环,curl_multi_poll() 等事件、curl_multi_perform() 推进状态。一个线程里同时跑一千个传输,靠的就是它。

驱动 multi 的是一台十六状态的机器:

INIT -> PENDING -> SETUP -> CONNECT -> CONNECTING
     -> PROTOCONNECT -> PROTOCONNECTING
     -> DO -> DOING -> DOING_MORE -> DID
     -> PERFORMING (<-> RATELIMITING)
     -> DONE -> COMPLETED -> MSGSENT
```

PENDING 是"没有可用连接、在排队",RATELIMITING 是"超过限速、故意干等",MSGSENT 是"完成消息已经交给应用、可以摘走了"。协议实现通过前面那张函数指针表挂在 DO/DOING/DOING_MORE 这几个状态上——FTP 的第二条数据连接就发生在 DOING_MORE

有意思的是 easy 接口并没有第二套实现:curl_easy_perform() 内部临时造一个 multi 句柄,把自己挂进去,然后转起来直到 MSGSENT保留 easy 接口不是为了性能,是为了那几亿行早就写好的调用代码。

向后兼容:一个 2006 年立下的承诺

libcurl 的 SONAME(动态库的 ABI 版本号)历史上只涨过四次,全部集中在头六年:

SONAME版本时间
0libcurl 7.12000 年 8 月
1libcurl 7.52000 年 12 月
2libcurl 7.72001 年 3 月
3libcurl 7.12.02004 年 6 月
4libcurl 7.16.02006 年 10 月

从 2006 年 10 月至今,SONAME 一直是 4。项目的原话是"我们决心尽可能少地提升 SONAME,理想情况下永远不再提"。实现方式只有一条铁律:只加不删。 curl.h 里用宏登记的 CURLOPT_ 选项有 287 个,其中一部分早已失去意义,但它们仍在表里,设置它们仍然返回成功——只是什么都不做。

配套的还有几条同样保守的规矩:源码承诺能被 C89 编译器编译,只要求 32 位以上的机器、一个 64 位整数类型和一个 C99 风格的 stdint.h;要删任何东西,先在 docs/DEPRECATE.md 里公告几个月到一年。这份公告文件读起来像一部微缩的计算史:Windows XP 支持删除于 2026 年的 8.19.0,Visual Studio 2008 支持删除于 8.18.0,SMB 与 NTLM 认证的移除日期定在 2026 年 9 月。

得到什么: 车厂敢把 libcurl 焊进一台十五年生命周期的车机,嵌入式厂商敢在一颗不会再更新工具链的芯片上用它。这份承诺本身就是 curl 能铺到三百亿台设备的原因之一——它把"升级依赖"这件事的风险降到了近乎零。

付出什么: 代码里永远背着没人用却不能删的分支。docs/CURL-DISABLE.md 里 45 个 CURL_DISABLE_* 编译期开关就是妥协的产物——不能删,那就让使用者自己在编译时关掉。

什么时候失效: 安全上。"永不删除"意味着攻击面永不缩小,更麻烦的是状态空间随选项数量持续膨胀。看 2026 年公布的 36 个漏洞就明白了:其中约一半集中在两类——"连接复用时匹配条件不完整"(复用了一条协议、代理、凭据或 mTLS 配置并不真正相同的连接)和"凭据在重定向或代理切换时泄漏"。连接复用要判断两次传输能否共用一条链路,需要比对的维度是二十多年累积下来的:协议、主机、端口、代理、代理凭据、认证方式、TLS 版本、客户端证书、SSH 主机密钥、netrc 配置……每加一个选项,这张比对表就要多一行,漏掉一行就是一个 CVE。截至 2026 年 8 月,curl 累计公布 206 个漏洞(2 个 critical、40 个 high、93 个 medium、71 个 low),其中 2026 年一年就有 36 个,且 6 月 24 日一天公布了 18 个。数量上升不是因为代码变差了,而是因为被翻找的密度上升了——这直接把我们带到下一个问题。

七个人的漏洞流水线

curl 的安全团队大约七个人。项目自 2024 年 1 月 16 日起是自己的 CNA(CVE 编号机构),可以自行分配 CVE 编号。流程写在 docs/VULN-DISCLOSURE-POLICY.md 里:收到报告后有人确认接收(历史中位数不到 1 小时),团队评估并定性(中位 36 小时),确认后写补丁、准备公告,发布前不超过 7 天通知发行版联络列表 distros@openwall,最后随版本发布同时公开。

2025 年 1 月,curl 宣布不再使用 CVSS 评分。理由不是嫌麻烦,而是它给出的数字对这类软件系统性偏高:CVSS 的输入项本来就假设你知道软件如何被部署,而 libcurl 的部署环境从服务器到打印机到心电监护仪。他们改用自己的四级判断(low / medium / high / critical),并拒绝为了迎合扫描器而补一个假的 CVSS 向量。

代价随之而来。CVE-2024-11053 被 curl 定为 LOW;CISA 后来把它标成 CVSS 9.1(CRITICAL),在公开质疑之后又改成 3.4。这一来一回中间,是全世界的合规扫描器同时报警、无数用户涌来提问,而回答问题的仍然是那七个人。当一个项目的评级权被外部机构接管,成本却留在维护者这边,"关键基础设施"这个词的重量就具体了。

赏金机制是另一条线。curl 的赏金计划 2019 年 4 月在 HackerOne 上线,最初的奖金出自 curl 自己收到的赞助捐款;2021 年 9 月并入重生的 Internet Bug Bounty 之后,奖金改由 IBB 的基金支付,curl 只保留"哪些问题够格拿奖"的判定权。到 2024 年 10 月的五年半统计:

指标数值
收到报告477 份(约每月 6 份)
确认为安全漏洞73 份(15.4%)
不是漏洞但是真 bug92 份(19.4%)
完全无关311 份(65.3%)
累计奖金84,260 美元
单个 CVE 平均奖金1,220 美元
典型档位low 约 500、medium 约 2,500、high 约 5,000 美元
领赏最多的人Harry Sintonen,25 份,29,620 美元

读这张表要看的不是 15.4%,而是 65.3%。赏金机制真正的成本不在奖金,在那 311 份必须被人读完、追问、判定、礼貌回绝的无效报告。 2021 年之后奖金由外部基金出,工时始终由这七个人出。在一个有安全工程部门的公司里,这道工序叫"分诊",有专人干;在 curl,它挤占的是同一批人写代码的时间。

AI 生成的报告:一种成本结构的翻转

2024 年 1 月 2 日,斯滕伯格写了一篇题为《LLM 里的 I 代表 intelligence》的文章,摆了两个例子。

一个是关于 CVE-2023-38545(SOCKS5 堆缓冲区溢出,2023 年 10 月 11 日公布,curl 评级为 high)的报告:提交者明说自己用了谷歌 Bard,报告断言"相关代码改动已经在互联网上公开"——这句话是假的,改动当时并未公开,模型把新旧两个安全问题编织在了一起。

另一个更麻烦。2023 年 12 月 28 日的一份报告,标题是 WebSocket 处理中的缓冲区溢出,英文流畅、结构完整、附带修复建议。斯滕伯格花了 19 分钟才开始怀疑,又经过多轮追问才确认:根本不存在那个溢出。

他给出的那句总结是这件事的核心:"垃圾做得越好,我们要花在它身上的时间和精力就越多。" 这是一次成本结构的翻转。以前一份错误的安全报告读三行就能判断,因为写得烂本身就是信号;现在写得好不再是信号,判断必须靠真读代码。生成一份看似专业的报告的成本坍缩到接近零,验证它的成本一分没少——甚至更高。

2025 年 7 月的续篇给出了量化:报告流入速度约每周两份,2025 年约 20% 是 AI 生成的,而真正有效的比例跌到 5% 以下。"每份报告都会牵动 3 到 4 个人,每人半小时,有时一到三小时。"斯滕伯格补了一句关键的话——他自己是全职做 curl 的,浪费三小时还有余地;他的同事不是。

时间线的收束值得完整列出:

时间事件
2019 年 4 月赏金计划在 HackerOne 上线
2021 年 9 月并入 Internet Bug Bounty,IBB 出 80% 奖金
2024 年 1 月 2 日《LLM 里的 I 代表 intelligence》,首次公开 AI 报告问题
2024 年 1 月 16 日curl 成为 CNA
2025 年 1 月 23 日宣布放弃 CVSS
2025 年 7 月 14 日《被一千份垃圾拖死》:20% 是 AI 生成,有效率跌破 5%
2026 年 1 月 26 日宣布终止赏金,1 月 31 日生效
2026 年 2 月 25 日宣布 3 月 1 日回到 HackerOne(GitHub 的私密报告功能缺分诊工具)
2026 年 7 月整月停止处理漏洞报告

终止赏金时的总账:累计支出超过 10 万美元,奖励了 87 个确认漏洞;而确认率从历史上的 15% 以上跌到 2025 年的 5% 以下。给出的三条理由是:AI 垃圾报告爆炸、非 AI 报告质量也在下滑、以及一部分研究者"以捅洞为目的而非以帮忙为目的"的心态。项目考虑过收取提交费用,最后否决了——跨国支付太复杂,而且会把没钱的诚实报告者一起挡在门外。

2026 年 7 月的做法最直白:整整一个月不处理任何漏洞报告。 HackerOne 页面上挂出"八月再来"。结果是几乎零报告涌入,只有一封私人邮件,被忽略了;没有客户受影响,也没有出现需要 CNA 七十二小时应急响应的情况。斯滕伯格事后写道,这"可能是我们很久以来最好的一个项目决定",团队形容那个月的感觉是"自由,卸下了锁链"。

值得反复看的是这一整串决定的做出方式:放弃 CVSS、终止赏金、换平台、再换回来、七月集体休假——没有委员会,没有法务审查,没有预算流程,没有向任何机构报备。 一个被三百亿台设备依赖的项目,它的安全策略是由不到十个人在邮件列表上商量出来的。这既是它敏捷的原因,也是它脆弱的原因,两者是同一件事。

可靠性建立在意愿之上

工程学处理关键系统的可靠性,靠的是一套可规划的东西。电网有 N-1 准则,任一元件退出系统仍要稳定;航空有冗余通道和最低设备清单;制造业有来料检验和备件库存。这些手段的共同点是:它们可以被写进预算、排进日程、写成采购条款。

curl 也有这类东西,而且做得相当好。八周一个发布周期,每个周期切成三段——发布后 10 天只修 bug 的冷却期、随后 21 天的特性窗口、最后 25 天的功能冻结;tests/data 目录下 2,056 个测试用例;三个候选版本分别在发布前 25 天、16 天、7 天放出。二十多年来这套节奏几乎没有断过。

问题在于,把这套节奏守住的不是流程,是人。对照一下:

工程可靠性手段curl 的对应物是否可规划
冗余元件(N-1)核心团队不到十人,历史提交量一人过半
备件库存没有法律实体,没有雇员,没有继任机制
定期检修八周发布周期、2,056 个测试用例
来料检验代码审查 + 每次提交跑的 CI 矩阵
供应商合同MIT 衍生许可证,唯一义务是保留版权声明否(无义务可言)
应急响应七人安全团队,CNA 身份,中位 36 小时定性部分
长期支持承诺SONAME 二十年不变,选项只加不删

表格右列的"是"全部是可测量、可审计、可写进采购合同的;而"否"的那几行,恰恰是整条链上最关键的部分。

2025 年 7 月的一件小事把这个不对称推到了极点:一家《财富》500 强公司为满足欧盟《网络韧性法案》的合规要求,向 curl 发来一份网络安全风险评估问卷,要求免费填写。斯滕伯格拒绝了,除非对方买支持合同。监管把义务放在下游的产品厂商身上,厂商把成本转嫁给上游的免费依赖,而上游是一个没有法律实体的项目。

斯滕伯格自己说他每周工作 50 到 55 小时,动力来自热情而非外部压力。这句话既是好消息也是坏消息:热情不能被采购,不能被排期,不能在他倦怠的那个季度按需扩容。这就是 curl 与 xz 真正共享的那个结构——xz 的维护者被人用三年时间蓄意耗尽,curl 的维护者被合规问卷、错误评分和 AI 生成的假报告日常性地磨损。两者的机制不同,作用点是同一个。

所以这个案例提出的一般问题不是"该给开源多少钱",尽管钱确实有用(主权科技基金这类机制正是对症的,斯滕伯格也公开支持过欧盟版本的提案)。真正的问题更硬:当整个数字世界的可靠性,在某些关键节点上取决于少数几个人是否还愿意在周末继续做这件事,而这种意愿既不能被采购、也不能被排期、更不能被冗余化时,我们的可靠性模型本身就是错的。 我们衡量软件供应链,靠的是版本号、依赖清单、CVE 列表和签名——这些都是可以自动化的。而唯一自动化不了的那一项,是最上游那个人明年还在不在。

跨域连接

  • 科学与技术研究(STS):拉图尔式的"黑箱化"描述了技术成功后的常态——一件设施越可靠,越没有人打开它看,直到它坏掉的那一刻才重新变成可见的对象——curl 是这个过程的教科书案例:三百亿份装机,却连准确的装机数都只能靠数车机"开源许可"页面来估计,因为没有任何机构有资格统计它。STS 强调技术物是异质网络的产物而非纯技术事实,这解释了为什么理解 curl 必须同时读它的函数指针表和它的治理文档:SONAME 二十年不变这件事,一半是工程决定,一半是一个人对下游几亿台设备的承诺,两者无法分开描述。
  • 电网:最大的实时平衡系统:电力系统在 2003 年大停电之后把"N-1 准则"写成规划底线——任一元件退出,系统仍要稳定——这条准则的前提是元件可以被冗余化、可以被库存、可以被计算。curl 在技术层面做到了对等水平:八周发布节奏、2056 个测试用例、三轮候选版本,全都是可审计的定期检修。但在人的那一层它连 N-1 都不成立:历史提交量一人过半,没有法律实体,没有继任机制。级联故障的类比在这里同样成立——真正危险的不是 libcurl 出一个 bug,而是维护带宽退出后,下游几万个项目同时失去补丁来源却没有任何一个准备好接手。
  • 公共品与市场失灵:curl 是非竞争、非排他的纯公共品,任何人可以免费使用、无法被排除,因此没有任何单一使用者有动机独自为它付费——经典结论是供给不足,而在软件里"供给不足"不表现为没人写,而表现为写的人太少:三百亿装机对应零收入,唯一稳定的资金渠道是一家 TLS 公司雇佣项目作者、靠卖商业支持回收成本。2025 年那份《财富》500 强公司发来的合规问卷把外部性写在了脸上——欧盟《网络韧性法案》把义务分配给了下游厂商,厂商把成本转嫁给上游的免费依赖,而上游没有法人、没有议价能力、也没有拒绝以外的手段。
  • 工作、劳动与组织生活:劳动社会学早就指出,把劳动等同于有薪就业会让大量维持系统运转的工作在统计里消失——curl 的维护正是这类劳动的极端形态:每周 50 到 55 小时,动力被描述为热情而非外部压力,组织形式是仁慈独裁者加一个不到十人的核心圈,没有雇佣关系、没有交接协议、没有休假制度。2026 年 7 月那次"整月不处理漏洞报告"之所以值得记住,是因为它是这套非正式组织唯一能自己发明的休假机制——不是制度给的,是几个人自己宣布的。而组织社会学关于倦怠的核心发现在这里完全适用:压垮人的很少是工作量本身,而是工作量不受自己控制。
  • 算法管理、工人权力与可审计工作:AI 生成的安全报告是一种未被命名的算法性劳动转嫁——生成一份看似专业的漏洞报告的边际成本坍缩到接近零,验证它的成本一分未减,甚至因为"写得越好越要认真查"而升高;成本被单向地推给了接收端那七个人。这与平台把调度、评级、申诉处理算法化之后劳动者所面临的处境同构:任务流入由对方控制,判断责任留在自己这边,而唯一的自保手段是退出——curl 的做法是终止赏金、停收一个月,代价是把真实的漏洞报告一起挡在门外。可审计性在这里是双向的:我们要求维护者对代码负责,却没有任何机制要求提交者对自己提交的东西负责。

参考文献

  • Daniel Stenberg 等, Everything curl(curl 项目官方手册,持续更新), 2015 年至今
  • curl 项目, libcurl ABI 与 API 稳定性说明(curl.se/libcurl/abi.html), 2026 年
  • curl 项目, GOVERNANCE.md — Decision making in the curl project, 2026 年
  • Daniel Stenberg, The I in LLM stands for intelligence, daniel.haxx.se, 2024 年 1 月 2 日
  • Daniel Stenberg, Death by a thousand slops, daniel.haxx.se, 2025 年 7 月 14 日
  • Daniel Stenberg, The end of the curl bug-bounty, daniel.haxx.se, 2026 年 1 月 26 日

延伸阅读

  • Nadia Eghbal, Working in Public: The Making and Maintenance of Open Source Software, Stripe Press, 2020 年——把"单人维护者"从个人品德问题重新表述为结构问题
  • Daniel Stenberg, CVSS is dead to us, daniel.haxx.se, 2025 年 1 月 23 日——为什么统一评分体系对无处不在的库会系统性失真
  • curl 项目, docs/internals/CONNECTION-FILTERS.md, 2022 年至今——连接过滤器的设计动机与栈式结构原文