编者注:匿名的代码是否真的无法破解?代码的开发人员是否能完美隐藏?新的研究表明可以利用机器学习技术对代码样本的作者进行去匿名化操作。这种操作对剽窃和隐私问题也会产生影响。本文将带你了解去匿名化研究目前的结果和未来的方向。
文体学(语言文体的统计分析)研究者—早就知道写作是一个独特的、个人主义的过程。您选择的词汇、句法和语法都会留下痕迹。例如,只要自动化工具有足够的培训数据可供使用,它们现在就可以准确地识别论坛帖子的作者。但最新的研究表明,文体学也可以应用于人工语言样本,比如代码。事实证明,软件开发人员也会有指纹留下。
雷切尔·格林斯塔特(Rachel Greenstadt)是美国德雷塞尔大学计算机科学的副教授。艾林·卡利斯坎(Aylin Caliskan)是格林斯塔特的前博士生、现任乔治·华盛顿大学助理教授。他们两人发现,代码和其他形式的文体表达一样,都是无法匿名的。在周五的DefCon黑客大会上,这两位科学家将展示他们的多项研究。在研究中,他们利用机器学习技术对代码样本的作者进行去匿名化操作。例如,他们的工作可能在剽窃纠纷中发挥作用,但同时它也有隐私问题,尤其是对成千上万向世界贡献开源代码的开发者而言。
如何对代码进行去匿名化?
下面用一个例子对研究人员如何使用机器学习来发现代码的作者进行简单解释。首先,他们设计的算法识别了在一些代码样本中找到的所有特征,有很多不同的特征。想想自然语言中存在的每一个方面:有你选择的单词,你把它们组合在一起的方式,句子长度,等等。格林斯塔特和卡利斯坎随后缩小了功能范围,使其只包含了真正区别于其他开发者的功能,将列表从数十万缩减到大约50个。
研究人员不依赖底层特性,比如代码的格式化方式。相反,它们创建“抽象语法树”来反映代码的底层结构,而非它的任意组件。他们的技巧类似于优先排序某人的句子结构,而不是在于他们是否缩进一个段落的每一行。
这个方法还需要一些别的工作来教一个算法,让它知道什么时候应该发现另一个代码示例。如果一个随机的GitHub账户弹出并发布了一个代码片段,格林斯塔特和卡利斯坎就不一定能够识别背后的人,因为他们只有一个样本可以使用。他们可能会说,这是一个他们从未见过的代码开发人员。然而,格林斯塔特和卡利斯坎并不需要把一生的时间都花在代码上,他们只需要几个短的样本。
例如,在2017年的一篇论文中,卡利斯坎、格林斯塔特和另外两名研究人员证明,即使是存储库站点GitHub上的一小段代码,也足以区分出各个编码者之间的区别,而且精确度相当之高。
最令人印象深刻的是,卡利斯坎和其他研究团队在另一篇论文中表示,只用他们编译的二进制代码就可以去匿名化程序员。在开发人员编写完一段代码后,一个名为编译器的程序将它转换成一系列的1和0,机器可以读取这些1和0,称为二进制。对人类来说,这简直就是胡说八道。
卡利斯坎和与她一起工作的其他研究人员可以将二进制分解回C++编程语言,同时保留开发人员独特风格的元素。假设您写了一篇论文,使用谷歌翻译将其转换为另一种语言。虽然文本看起来可能完全不同,但是您编写的方式元素仍然嵌入到了语法之类的特性中。代码也是如此。
“风格被保留了下来,” 卡利斯坎说。“当文本是以个人学习为基础时,就会有很强的风格特征。”
为了进行二进制实验,卡利斯坎和其他研究人员使用了谷歌 Code Jam年度编程挑战赛的代码样本。机器学习算法正确地识别出了100名个体程序员,而只用了96%的时间。每个人使用8个代码样本。即使将样本量扩大到600名程序员,该算法仍能在83%的时间内准确识别。
对剽窃和隐私的影响
格林斯塔特和卡利斯坎说,他们的工作可以用来判断编程学生是否有抄袭行为,或者开发者是否违反了雇佣合同中的非竞争条款。安全研究人员可能会使用它来帮助确定创建一种特定类型恶意软件的可能开发人员。
更令人担忧的是,一个威权政府可能会使用去匿名化技术来识别背后的个人,比如说,一个规避审查的工具。这项研究还对那些为开源项目做贡献的开发人员有隐私方面的影响,特别是如果他们一直使用相同的GitHub账户的话。
格林斯塔特说:“人们应该意识到,在这种情况下,要百分之百地隐藏自己的身份是非常困难的。”
例如,格林斯塔特和卡利斯坎发现,一些现成的混淆方法,即软件工程师用来使代码更复杂、安全性更高的工具,并不能成功地隐藏开发人员的独特风格。然而,研究人员说,在未来,程序员可能能够使用更复杂的方法隐藏他们的风格。
“我确实认为,只要我们继续进行下去,将会发现一件事,那就是什么样的混淆方法能够掩盖这些东西。” 格林斯塔特说:“我不相信,最后发现的结论是你做的每件事都是有迹可循的。无论如何,我希望不是这样。”
例如,在另一篇论文中,由华盛顿大学的露西 ·西姆科(Lucy Simko)领导的团队发现,程序员编写代码的目的可以是让算法相信自身是别的程序员编写出来的。该团队发现,即使开发人员没有专门训练过如何创建赝品,他们也可能会对自己的“编码签名”进行恶搞。
未来的研究方向
格林斯塔特和卡利斯坎还发现了许多关于编程本质的有趣见解。例如,他们发现经验丰富的开发人员比新手更容易识别代码。你越熟练,你承担的工作就越独特。部分原因可能是因为初级程序员经常从Stack Overflow这样的网站复制粘贴代码解决方案。
同样,他们发现,解决更困难问题的代码示例也更容易属性化。通过使用62名程序员组成的样本,这62名程序员每个人都解决了7个“简单”的问题,研究人员在90%的时间里都能够将他们的工作去匿名化。当研究人员使用7个“困难”问题样本时,他们的准确率下降到95%。
在未来,格林斯塔特和卡利斯坎想要了解其他因素是如何影响一个人的编码风格的,比如当同一个组织的成员在一个项目上合作时会发生什么。他们还想探究一些问题,比如来自不同国家的人是否会以不同的方式编码。例如,在一项初步研究中,他们发现他们可以区分加拿大和中国开发者编写的代码样本,准确率超过90%。
还有一个问题,相同的属性方法是否可以在不同的编程语言中以标准化的方式使用。目前,研究人员强调,尽管到目前为止他们的方法已经被证明是有效的,但是去匿名化代码仍然是一个神秘的过程。
“我们仍在努力弄清楚哪些是真正可以属性化的,哪些不是。”格林斯塔特说:“有足够的理由证明,这些应该引起关注,但我希望这不会导致任何人都不公开发表意见的糟糕情况发生。”