Hey! JavaScript Developer, someone is stealing your bitcoin!

To summarizes this event:

  1. copay-dash is a popular bitcoin platform which includes event-stream as a dependency.
    copay-dash 是一个很流行的比特币平台,它使用了event-stream作为依赖包。
  2. For about a week in September, event-stream included flatmap-stream as a dependency, as it was passed along to a new maintainer who added the dependency and removed it a week later.
    九月份的时候,event-stream 使用了flatmap-stream作为依赖报,它传给了一个新的维护者,这个维护者加上了这个依赖包,一周之后又删掉了。
  3. flatmap-stream had some code hiding at the end of its minified built output which attempts to decode and execute strings from its packaged test/data.js file, using the description of the top-level package as the AES256 key.
    flatmap-steam 隐藏了一些代码在压缩代码的最后,它尝试使用顶级包的描述中的AES256 key去decode并且运行在test/data.js的字符串.
  4. For any other package, this produces a silently handled error (as the package description/decryption key is wrong). But for copay-dash, this produces some valid JavaScript which runs another round of decryption and executes a malicious script that steals your bitcoin wallet.
    对于其他包,这些产生了轻微的错误(被try catch了),但是对于copay-dash, 它产生了有效的JavaScript代码,运行另一轮解密并执行了偷取比特币的恶意脚本。

What now?

  1. Use a lockfile. Whether it’s yarn’s yarn.lock or npm’s package-lock.json, a lockfile ensures that you get the same package versions on every install, so if you’re secure today then you’ll be secure tomorrow as well. Apps that utilize floating dependencies without a lockfile are particularly vulnerable to malicious updates, because they will automatically install the latest patch version of their dependencies — meaning that you may be compromised as soon as your next deploy, if one of your dependencies is compromised and publishes a malicious patch. With a lockfile, you at least limit your exposure to manual developer actions that add or update a package, which can be double-checked via code reviews and organizational policies.
    使用lockfile, 比如说yarn.lock 或者package-lock.json。 lockfile文件确保了你每次install都会拿到相同版本的依赖包,所以如果你这次安装是安全的,那你下次也是安全的。如果你没有使用lockfile, 下载依赖包的时候会默认下载最新的版本,意味着你可能下载了一个含有恶意代码的版本。如果你某个依赖包遭到了破坏并发布了恶意版本,有lockfile的话,你至少可以限制对于手动添加、更新依赖包的风险,因为可以在代码审查、组织的时候double-check。

  2. Think before you install. This isn’t a panacea — as demonstrated above, it’s easy for attackers to slip malicious code into minified output, which is hard to find even if you knew it was there. But you will drastically reduce your exposure if you stick to popular, well-maintained packages. Before you install a new dependency, first, ask yourself if you really need it. If you already know how to write the code, and it won’t take you more than a few dozen lines, just do it yourself. If you do need the dependency, scope it out before you install. Does it have high download numbers on npm? Does the GitHub repo appear well-maintained and active? Has the package been updated recently? If not, also consider forking the repository and either publishing a fork to npm or installing the package directly from your GitHub; this reduces risk because you aren’t exposed to future malicious updates, and you can read and minify the source yourself so you’re confident about what it really does.
    下载前三思。这不是万能药 – 正如前面所示范的,将恶意代码写进压缩输出很简单,但是找出来很难,即使你知道它在。但是你会大大减少你的曝光率,如果你坚持使用流行的、维护好的依赖包。在你下载一个新的依赖包前,首先,问下你自己你真的需要吗?如果你已经知道怎么去写这段代码,而且不会很多,不如自己写。如果你真的需要这个依赖包,在你下载前确定范围,它有很高下载量吗?它的Github看起来最近有没有好好在维护?最近有更新吗?如果没有,也考虑下fork这个仓库而且将fork发不到npm或者直接从github下载包。这将减少风险,因为你没有暴露在未来可能的恶意更新中,而且你可以阅读、压缩源代码,知道它究竟在干什么。

原文