2023年11月的第一篇阅读推荐,我们介绍的是IEEE S&P 2024的论文Measuring the Effects of Stack Overflow Code Snippet Evolution on Open-Source Software Security
首先提一个问题,你觉得GitHub上面的代码,有多少是复制粘贴过来的?很多GitHub上的开发者其实并不是专家,他们写代码的时候也会去参考很多其他的信息,除了那些直接fork的项目,很多项目里面的代码片断(code snippet,这里到底用“片段”还是“片断”,欢迎大家各抒己见)实际上来自于论坛、维基和问答网站,而我们最熟悉的Stack Overflow网站就是一个超级超级重要的代码片断来源。本文的作者对Stack Overflow上关于编程和代码的帖子进行了调研,关注它们对GitHub上存在的代码的影响。那这个调研具体是怎么进行的呢?请继续看文章的细节。
首先,我们要了解下Stack Overflow的问答帖子的版本控制特点。在Stack Overflow上,并非所有问题提出之后,回答就永远一成不变,而是会随着时间的推移有所修订。例如下面这个问题和对应的回答,在2009年的初始答案提出后,2011年进行了首次修订。差不多10年之后,到了2021年,有人指出这个代码存在一个XML eXternal Entity(XXE)注入问题:
实际上,这个问题的答案最后经过了4次修订,Stack Overflow提供了版本控制机制,浏览者可以看到不同的版本,这也为研究人员提供了便利:类似有一些研究工作去分析Git的commit信息,本文也利用了Stack Overflow上面问题答案的可追溯性,分析各种答案的历史错误,然后再交叉比对GitHub,看有多少代码受到了影响。
我们首先介绍一下下图所示的作者研究流程:
-
从Stack Overflow和GitHub上分别收集代码;
-
对两个网站上收集的代码进行相似性比对,特别注意要考虑代码的历史版本;
-
找到最匹配的代码对;
-
对Stack Overflow代码片断,标记那些“过气”(outdated)的代码片断和最新的代码片断;
-
忽略那些没有评论(comment)也没有提交信息记录(commit message)的outdated代码片断;
-
对存在评论或提交信息记录的Stack Overflow代码片断,检查其中和安全相关的信息,如果存在,再去GitHub代码中寻找是否有项目使用了这种存在安全问题的outdated代码片断
作者给出了如下的统计表格,标记了所调查的Stack Overflow代码片断(涉及四种编程语言)中,最终产生了超过10行以上代码变化的情况:大约有四分之一的代码片断,其最终的版本和最初回答时是不一样的。
作者的实验使用了2020年12月31日版本的SOTorrent
,这是一个专门保存Stack Overflow文本和代码(包括变更)信息的数据集,其中包含了31 287646个代码片断;同时还从GitHub上抓取了11479个独立的项目((Java项目数量:2290;C项目数量:2241;项目数量:Python项目数量:3107;JavaScript项目数量:3841),其中包含了4098397个源代码文件。
为了检测代码的相似性,作者使用了两个工具:NiCad
和PMD Copy-Paste Detector
,前者用来检测Java和C代码的相似性,而后者可以检测Python和JavaScript代码的相似性。利用这些工具,作者发现了3439个GitHub项目中108134个代码片断(可能)是从Stack Overflow问答中复制粘贴过来的。当然,要确定到底哪些片断是不安全的,还需要很多分析,这部分内容可以从论文的4.1.3章到4.1.5章中找到详细的答案。我们就直接给结果了:
重点介绍一下一些关键的结论吧。首先是在Stack Overflow问答帖子中,有2290个帖子确实影响到了GitHub项目中的代码(引入了潜在的安全问题),而这些帖子中有505个(22%)帖子(其中包括278个答案和227个问题)涉及到了针对安全的讨论,不过其中只有一个问题帖子和25个回答帖子包含了对此前不安全代码的修复信息。而在GitHub项目中,作者发现有43个项目包含了已经在Stack Overflow问答帖子被人讨论、确认有安全问题的代码(这好像不失为一种挖掘CVE的方法?):
作者在论文中重点讨论了一个问题编号为#122721
的实例,这个问题的标题是How do i trim leading/trailing whitespace in a standard way? (可以在 https://stackoverflow.com/a/
122721/8462878 访问)。在这个例子的原始回答中,由于没有给isspace
的输入进行无符号类型(unsigned char)转换,会导致未定义行为。而在有人留言指出这个问题(这时候距离原始回答已经过去了8年)不到一个月以后,原始的代码进行了更新,增加了cast操作。
不幸的是,由于这份代码的安全问题隔了8年才有人指出,在这期间,有4个GitHub项目直接复制粘贴了这个答案,引入了不安全的代码,作者用下面的timeline来描绘了整个事件发生的顺序:
实际上,在论文的附录中还有好些例子,作者也在下表中列出了他们的详细发现(其实之所以要贴这个表出来,是要提醒大家,这里面第三个项目实在是太辣眼睛了蛤蛤蛤)。
论文:https://www.computer.org/csdl/proceedings-article/sp/2024/313000a022/1RjE9YN9TQ4
原文始发于微信公众号(安全研究GoSSIP):G.O.S.S.I.P 阅读推荐 2023-11-01 尽信书,不如无书
- 我的微信
- 微信扫一扫
-
- 我的微信公众号
- 微信扫一扫
-
评论