写点什么

为什么 StackOverflow 上的代码片段会摧毁你的项目

  • 2020-11-27
  • 本文字数:2585 字

    阅读完需:约 8 分钟

为什么StackOverflow上的代码片段会摧毁你的项目

本文最初发布于Mahdhi Rezvi个人博客,经原作者授权由 InfoQ 中文站翻译并分享。


在 StackOverflow 上你会惊奇地发现,上面分享的一些解决常见问题的代码居然存在安全漏洞。


包括我在内,现在 StackOverflow 已经成为许多程序员的救星。我们中的大部分人甚至从未访问过 StackOverflow 的主页。我们访问该网站的唯一方式,是通过谷歌搜索某个我们遇到的问题或 bug,然后直接进入该问题的讨论区。


尽管去 StackOverflow 上寻找问题解决办法的习惯很实用,但与此同时我们可能也会无意中使用一些包含严重 bug 或者安全缺陷的代码。众所周知,直接从 StackOverflow 上复制代码来用是不合适的,但开发人员仍会这么做,这里引用 Ryan Donovan 的一句话:


代码复制本身并非坏事,代码重用能提高软件开发效率。为什么已经被完美解决的问题,还要再去重新解决一次呢?但是当开发人员不加理解就去使用示例代码时,那么问题就来了。


你可能会认为那些安全恐慌都只是都市传说,但我可以向你保证并不是。


最近我遇到的几件事,引起了我对这个问题的关注,下面我把这几件事简单说明下。



插图Mateusz Kupilas提供


StackOverflow 上拷贝次数最多的 java 代码片段,一直都存在缺陷。


首次知道这个信息是在一篇博客中读到的,而这篇博客的作者正是那个 java 代码的提供者,点击这里查阅博客原文。


Andreas Lundblad 是这段代码的作者,他是 Palantir 的 Java 开发人员,同时也是 StackOverflow 上排名最高的贡献者之一,他在博客中承认了此代码的缺陷。


2018 年,Sebastian Baltes 在《实证软件工程》期刊上发表了一篇研究论文。该论文指出 Andreas 在 StackOverflow 上发布的一段 Java 代码是 StackOverflow 上被拷贝次数最多的 Java 代码,甚至被多次使用在开源项目中,在 GitHub 上至少有 6000 多个 Java 项目使用了该代码片段。


该段代码是为了回答于 2010 年发布在 StackOverflow 上的这个问题。它的功能是将字节计数转换为更易于阅读的格式。例如,它将 1024 字节转换为 1kB 或将 1048576 字节转换为 1 MB。


Andreas 在被 Sebastian Baltes 告知这段代码的惊人传播量后,重新评审了这段代码。且随后在其个人博客中发布了更正后的版本,同时在博客的最后还给出了一些有价值的建议:


  • StackOverflow 上的代码段可能存在 bug,即使它们有成千上万的赞成投票。

  • 测试所有的边缘情况,特别是从 StackOverflow 复制的代码。

  • 在复制代码时,一定要包括其来源和贡献者,当出问题时,能快速定位。


尽管这个 bug 是一个微不足道的边缘情况,只会导致对文件大小计算的不精确,但实际情况可能会更糟,我们来看更多的例子。


StackOverflow 上流行最广的 c++代码片段存在重大安全缺陷


2019 年,Morteza Verdi 等人发表了一篇研究论文。该论文指出,过去 10 年里,StackOverflow 上流行最广的 c++代码片段中有 69 个存在重大安全漏洞。这 69 个经确认易受攻击的代码片段被使用到了 2589 个 GitHub 项目中。据研究者指出,从 StackOverflow 传播到 GitHub 上的这些代码中,最常见的安全漏洞是CWE150:


CWE 是社区开发的常见软件和硬件安全缺陷列表。它是一种通用语言,是安全工具的衡量标准,同时也是缺陷识别、规避和预防的基础。


CWE150 指的是空间、元空间或控制空间出现不适当中和的情况。


该论文的研究人员还开发了一个 chrome 扩展,当开发者查看 StackOverflow 代码片段时可以提醒开发者当前阅读的代码是否存在安全漏洞。虽然这个扩展一般用途不大,不过如果感兴趣的话,可以点击这里查看它的源代码。


不能在 Windows 上同时运行 Docker 和 Razer Synapse 驱动管理工具,因为他们存在 StackOverflow 式的 bug


大约 2 年前,在 Windows 上运行 Docker 时有个奇怪的现象,即用户无法在 Windows 系统的机器上启动 Docker。这个奇怪的现象后来被人以问题的方式在 Github 提了出来。随后有很多其他人也说遇到了相同的问题。直到 Reddit 上的这篇文章发布之前,都没人知道根本原因是什么。


该文章指出,当 Windows 后台启动了 Razer Synapse 时,此时再去启动 Docker 就会触发此问题。其原因是,在 Razer Synapse 运行的时候,Docker 会认为已经有一个 Docker 实例正在运行中,所以 Docker 不会再启动一个实例。


两个应用程序各自都只允许同时启动一个自己的实例,这个需求看上去是个再合理不过的需求了。但是现实却是,这个限制确实是该 bug 的根本原因。下面是引发问题的代码片段:


var name = string.Format("Global\{0}", (object) Assembly.GetExecutingAssembly().GetType().GUID);
复制代码


从上面的代码可以发现,问题就出在返回的 GUID 类型上。此处返回的 GUID 类型是 System.Reflection.RuntimeAssembly(系统层面的运行时程序集),而不是 Windows 中对应 Docker 程序集中定义的类型。


译者注:以上代码说明,在控制同一时间只允许运行一个实例,Docker 的处理方式是通过判断 GUID 是否存在,但获取在 GUID 时,用的是系统层面的而非自己独立程序集里面的。


更有趣的事情是:


如果只有一个应用程序使用了上面的错误代码,那么上述问题根本就不会出现。但现实是,很多应用程序都使用了该错误代码,结果不允许两个实例同时运行。


你认为上面两个应用程序包含的错误代码片段是从哪里来的呢?


我想你已经猜到了,没错,正是来自于 StackOverflow。


在.net2.0中应用如何通过程序拿到GUID,这篇不正确的 StackOverflow 文章,就是这些应用程序错误代码的来源。


你现在去看问题的答案,已经看不到有缺陷的回答了。他们已经重新编辑了答案。如果你想自己手动去查找,可以通过Wayback Machine来查看历史文章,查询结果如下图:



截图由Кекек Мачан提供


对开发人员的重要启示:


  • 考虑一下如何在自己的程序中找到这个 bug

  • 你所拷贝的代码表面上似乎能正确的运行,但其实你没有意识到的是,此代码本身就是缺陷代码——因为你的程序中没有引发错误的场景


所以,我们该避免拷贝吗?


并非如此,直到今天,Stack Overflow 对于任何程序员来说,都是必不可少的。但在项目中因拷贝代码引起的大多数问题都是基本的安全问题。因此如果你能事先弄懂你所拷贝的代码,那么是可以正确使用的。即使如此,当准备在生产环境中使用这些代码时,也最好先做好充分的测试,特别是一些边缘场景,下面引用 Ryan Donovan 的一句话:


“如果你引用别人的代码,但你却不理解所引用代码的内容;那么您就会陷入重用具有潜在漏洞的代码的陷阱,同时这些包含漏洞的代码也就被你传播开了。”如果您要重用代码,那么请您先理解这些代码。


祝您编程愉快!


原文链接:


Why Code Snippets From Stack Overflow Can Break Your Project


2020-11-27 17:001768

评论

发布
暂无评论
发现更多内容

北鲲云超算与传统的超算中心有什么不同?

北鲲云

喜讯:恒拓高科荣获“2020年度华侨城集团优秀数字化服务商”称号

BeeWorks

开源 解决方案 即时通讯 开源软件

MySql 通过定义变量更新多表

Flychen

【从零开始学爬虫】采集京东商品信息

前嗅大数据

大数据 爬虫 数据采集 采集商城 采集京东

视觉生产技术入门篇

若尘

视觉 7月日更

干掉 Postman?测试接口直接生成API文档,这个工具贼好用

程序员小富

Java 编程 程序员 开发工具 大学生

Redis on AEP 实践

BUG侦探

redis 傲腾AEP

事件Event:带你体验鸿蒙轻内核中一对多、多对多任务同步

华为云开发者联盟

鸿蒙 任务 OpenHarmony 事件 LiteOS-M

面试官:order by 是怎样排序的?怎么优化?

一个优秀的废人

Java MySQL 数据库 后端 order by

优评海洋APP系统开发模板

科创人|决策易赵祝维:从满足应用需求到服务业务目标,从SaaS服务商到业务合作伙伴

科创人

国内首发!阿里高工手码分布式系统速成笔记!

Java 编程 程序员

ZooKeeper 分布式锁 Curator 源码 01:可重入锁

程序员小航

zookeeper 源码 分布式锁 curator

电脑有什么超简单的录屏方法

淋雨

视频剪辑 Camtasia 录屏软件

我可以减肥失败,但我的 Docker 镜像一定要瘦身成功!

尔达Erda

Docker 开源 云原生 镜像 瘦身

名列GitHub必看榜!腾讯架构师纯手敲Spring Boot高级进阶笔记

Java架构追梦

Java 架构 腾讯 面试 springboot

华为首次发布HarmonyOS职业认证,助力开发者实现职业进阶

科技汇

Gemini Mining双子矿业系统APP开发模板

WorkPlus综合企业数字化解决方案—华侨城

BeeWorks

企业 移动开 开源软件

华为云GaussDB(for openGauss)推出重磅内核新特性

华为云开发者联盟

高可用 华为云 内核 GaussDB(for openGauss) 存储引擎

了解一下缓存分类、更新、清理策略以及如何处理缓存带来的风险

Jokay

缓存 缓存穿透 缓存击穿 缓存雪崩 缓存设计

网络攻防学习笔记 Day76

穿过生命散发芬芳

网络攻防 7月日更

商业智能BI,会成为下一个风口吗?

瓴羊企业智能服务

阿里云 数据中台 数据分析 BI 商业智能

HarmonyOS Connect伙伴峰会重庆站举办 生态建设持续完善

科技汇

从Encoder-Decoder模型入手,探索语境偏移解决之道

华为云开发者联盟

神经网络 ASR 语境偏移 CLAS ASR模型

阿里云低延时直播 RTS 能力升级 让直播推流效果更佳

阿里云CloudImagine

阿里云 音视频 直播技术 视频云

PHA挖矿|PHA云算力挖矿系统开发案例

Geek_23f0c3

区块链 云算力挖矿系统开发详解 PHA矿机挖矿

10分钟理解REACT概念

加百利

React 7月日更

Ubuntu Server 20.04搭建Redis集群

玏佾

redis redis集群 搭建 redis cluster

BTAU比特金盾系统软件开发内容

深度解析HashMap底层实现架构

华为云开发者联盟

Java hashmap 底层 底层架构 Map接口

为什么StackOverflow上的代码片段会摧毁你的项目_语言 & 开发_Mahdhi Rezvi_InfoQ精选文章