使用Vendetect大规模检测代码抄袭
无人谈论的代码依赖问题
在安全评估过程中,我们经常遇到包含其他项目复制粘贴代码的代码库。有时这是合法的依赖管理,但很多时候并非如此。这些问题比单纯的许可证违规更加严重:
-
安全债务悄然累积:当开发者从OpenSSL依赖函数或从OpenZeppelin复制智能合约工具时,他们会继承该代码中的任何潜在漏洞。但如果不跟踪源版本,当CVE发布时你无法知道自己是否受影响。
-
归属信息消失:我们见过包含完整开源库但删除版权声明的专有代码库。无论是恶意还是意外,这都会产生法律责任。
-
更新永远不会发生:依赖的代码会随时间冻结。原始项目修复错误并添加功能,但复制版本会逐渐腐化。
Vendetect的工作原理
Vendetect实现了Winnowing算法,这是斯坦福MOSS抄袭检测器使用的方法,在计算机科学教授中很受欢迎。但我们已将其适配到现实世界的软件工程需求。
该算法通过创建代码的语义指纹来工作,即使发生表面级更改,这些指纹也能保持稳定。以下是简化过程:
- 使用语言感知词法分析器(通过Pygments)对代码进行标记化
- 从标记流生成k-gram
- 对k-gram进行哈希处理,并使用滑动窗口选择子集
- 比较文件间的指纹以查找匹配项
这种方法即使在有人进行以下操作时也能捕获复制的代码:
- 重命名所有变量和函数
- 删除注释和文档
- 重新格式化或重构代码
- 将制表符更改为空格
我们构建了Vendetect的模块化架构;Winnowing实现只是一个检测后端。该工具可以轻松集成其他方法,如JPlag基于标记的匹配或基于AST的相似性检测。我们使用Python copydetect包作为核心Winnowing实现,这为我们提供了速度和可靠性。
版本控制感知改变一切
这是Vendetect与学术抄袭检测器的不同之处:它能理解git历史。
假设你正在审计代码库并发现可疑的加密实现。Vendetect不仅告诉你它匹配某些OpenSSL代码,还会识别出它被复制的确切提交。现在你可以检查该版本是否具有Heartbleed漏洞,或自那以后修复的数十个内存损坏错误。
此功能在评估过程中被证明非常宝贵。我们发现了:
- 包含具有已知错误版本的依赖OpenZeppelin代码的智能合约
- 从包含弱点的预披露提交复制的加密库
- 从带有硬编码后门的教程中提取的身份验证代码
该工具自动克隆和分析存储库历史,将你的目标代码库与多个版本进行比较,以找到最可能的源提交。
实际检测案例
在笔记本电脑上对Cheating-Daddy/Glass案例运行Vendetect大约需要10秒:
|
|
结果清楚地显示了跨多个文件的广泛复制,具有高相似性分数,尽管Glass试图通过删除注释和重新格式化来掩盖来源。
在智能合约评估中,依赖检测更为关键。以太坊开发者经常从成熟项目中复制实用函数、数学库和安全模式。虽然这通常是合法的,但这种做法会创建隐藏的依赖关系。
在实践中使用Vendetect
安装很简单:
|
|
基本用法比较两个存储库:
|
|
默认的丰富输出显示并排代码比较与相似性百分比。JSON输出可轻松集成到CI/CD管道中,用于自动化许可证合规性或安全检查。
超越抄袭检测
我们构建Vendetect是为了解决在安全评估过程中遇到的实际问题,但其应用超出了捕获代码窃贼的范围:
- 供应链安全:识别代码库中的所有依赖依赖项,特别是传统依赖项管理器未跟踪的依赖项。
- 许可证合规性:自动验证依赖代码是否保持适当的归属和兼容许可。
- 安全补丁跟踪:当宣布CVE时,通过与修补版本进行比较,快速检查你的依赖代码是否受影响。
- 代码考古学:当文档缺失或不正确时,追踪遗留代码的谱系。
扩展Vendetect
Vendetect的模块化架构使得尝试不同的检测算法变得容易。如果你实现了自己的相似性检测方法,无论是基于AST分析、机器学习嵌入还是新颖算法,我们都希望听到你的消息。该工具为添加新的检测后端提供了清晰的接口:
|
|
我们对在特定领域(如智能合约或嵌入式系统)可以改进检测的方法特别感兴趣,在这些领域中传统的基于文本的匹配会失败。
亲自尝试
下次你怀疑代码被复制时,无论你是调查许可证合规性、追踪漏洞来源,还是只是对代码出处感到好奇,都可以试试Vendetect。
该工具可在GitHub和PyPI上获得。如果你实现了新的检测后端或找到了有趣的用例,请联系我们。我们始终根据实际需求改进工具。
代码依赖不会消失。但通过适当的工具,我们至少可以使其可见、可跟踪和可管理。因为当你甚至不知道安全债务存在时,它的累积速度最快。