[Paper] 不安全且未使用?成熟开源项目中的 Utility Code 历史
发布: (2026年5月1日 GMT+8 01:32)
7 分钟阅读
原文: arXiv
Source: arXiv - 2604.28146v1
概览
本研究调查了七个长期存在的开源项目中 “util”(实用工具)文件的生命周期,探讨这些万用模块是保持有用、成为安全隐患,还是在代码库成熟后仅仅闲置。通过对跨越 147 项目年、30 天快照的挖掘,作者揭示了令人惊讶的模式,能够帮助开发者在今天做出更明智的命名和模块化选择。
关键贡献
- 大规模纵向分析 1,773 个快照,覆盖七个成熟项目(Linux kernel、Django、FFmpeg、httpd、Struts、systemd、Tomcat)。
- 重命名追踪方法,跟踪每个 util 文件的重命名、移动和删除,保留其完整历史。
- 实证证据表明,util 文件导致安全漏洞的可能性是非 util 文件的 2.75×。
- 量化洞察,揭示 util 文件的复杂度、开发者所有权和协作随时间的演变。
- 可操作的指南,帮助在新项目和现有项目中避免“不安全且未使用”的工具代码。
方法论
- 项目选择 – 七个广泛使用、积极维护的开源系统,且拥有至少十年的 Git 历史。
- 快照创建 – 每 30 天获取一次完整的仓库快照,累计得到 1,773 个数据点。
- Util 标识 – 将路径中包含子串 “util”(不区分大小写)的文件标记出来。
- 重命名追踪 – 使用 Git 的重命名检测,跟踪每个 util 文件在移动和重命名过程中的变化,以保持其生命周期的连续记录。
- 指标提取 – 对每个快照,作者测量以下指标:
- 使用情况(导入/调用频率)
- 复杂度(圈复杂度,代码行数)
- 开发者活动(贡献者数量,代码 churn)
- 安全事件(CVE,提交标记的修复)
- 统计分析 – 采用相关性和生存分析技术,对 util 文件与非 util 文件在各测量维度上的差异进行比较。
结果与发现
- 普遍性:Util 文件可能占代码库的相当大比例(例如,Tomcat 文件的 17.9 %)。
- 漏洞风险:Util 文件被卷入 CVE 的可能性是其他文件的 2.75×,即使在控制了大小和复杂性之后。
- 寿命与 churn:许多 util 文件多年保持几乎不变,表明它们成为“死重”,而非积极维护的工具。
- 复杂度增长:随着时间推移,util 文件往往累积比相应的非‑util 模块更高的环路复杂度(cyclomatic complexity),可能是因为它们成为不相关辅助代码的存放地。
- 协作模式:Util 文件通常拥有 更广但更浅 的贡献者基础——很多开发者会触及它们,但真正负责的少,这导致质量和审查实践不一致。
- 重命名动态:约 30 % 的 util 文件至少被重命名或移动一次,表明有组织或淘汰的尝试,但许多仍保留 “util” 名称,即使功能已漂移。
Practical Implications
- 命名规范: 将 “util” 视为 临时 标签。如果一个辅助工具的功能超出单一、明确定义的目的,应将其迁移到特定领域的包中。
- 代码审查重点: 鉴于 util 文件更易出现漏洞,应优先进行安全审查和静态分析。
- 所有权分配: 为实用模块指定明确的所有者或 “管家”,以避免 “人多无策” 的问题。
- 重构节奏: 安排定期审计(例如每季度),识别陈旧的 util 代码,合并重复的辅助工具,并清除无用的实用程序。
- 工具支持: 在 CI 流水线中加入脚本,标记包含 “util” 的新文件,并在合并前强制执行检查清单(目的说明、单元测试、所有权)。
- 架构指导: 鼓励开发者设计小而内聚的库,而不是单一的 util 包,这有助于提升可测试性并降低攻击面。
限制与未来工作
- 命名偏差: 该研究仅捕获路径中包含 “util” 的文件;使用其他约定(例如 “common”、 “helpers”)的项目未被纳入。
- 语言范围: 所有七个项目主要使用 C、Java 或 Python;对于具有不同模块系统的语言(例如 Rust、Go),结果可能会有所不同。
- 因果关系 vs. 相关性: 虽然 util 文件与更高的漏洞率相关联,但分析无法明确证明命名约定导致了风险。
- 未来方向: 将方法扩展到其他命名模式,探索用于 util 清理的自动重构工具,并研究 util 代码在大型微服务生态系统中对性能和可维护性的影响。
作者
- Brandon Keller
- Kaitlin Yandik
- Angela Ngo
- Andy Meneely
论文信息
- arXiv ID: 2604.28146v1
- 分类: cs.SE
- 出版日期: 2026年4月30日
- PDF: 下载 PDF