微信号:frontshow

介绍:InfoQ大前端技术社群:囊括前端、移动、Node全栈一线技术,紧跟业界发展步伐。

你的JavaScript依赖库可能并不安全

2018-08-26 16:53 无明 译
作者|Manjunath M
译者|无明

现代的 JavaScript 开发人员都喜欢 npm。GitHub 和 npm registry 是开发人员在查找特定软件包时常去的地方。开源模块为开发人员提供了很多可在项目中重用的功能,帮助他们提高工作效率。可以说,如果不是这些开源软件包,今天的大多数框架都不会以当前的形式存在。

一个成熟的企业级应用程序可能依赖数百个(如果不是数千个)软件包。通常的依赖包括直接依赖、开发依赖、捆绑依赖、生产依赖和可选依赖。

然而,人们通常忽视了存在软件包中的风险。虽然这些第三方模块在某些方面特别有用,但也会往你的应用程序中引入一些安全风险。

开源库是否有漏洞?

OSS 软件包确实存在漏洞,容易遭受攻击。我们来看几个例子:

最近在一个名为 eslint-scope 的软件包中发现了一个漏洞,它是一些流行的 JavaScript 软件包(如 babel-eslint 和 webpack)的依赖项。这个软件包维护者的帐号遭窃取,黑客在其中添加了一些恶意代码。所幸的是,有人很快发现了这个漏洞,最后只影响了少数几个用户。

Moment.js 是用于解析和显示日期的常用 JavaScript 库之一,最近出现了一个漏洞,严重性评分高达 7.5。这个漏洞容易遭受 ReDoS 攻击。不过他们很快发布了补丁, 问题也将很快得到解决。

5 月份,npm 中出现了一个伪装成 cookie 解析器的后门程序, NPM 在接到投诉后迅速将其移除,好在没有造成任何真正的破坏。

今年早些时候,GitHub 就开始提醒开发人员他们的代码中包含不安全的库。

GitHub 平台负责人 Sam Lambert 在最近的媒体采访中表示,他希望能够通过机械化提交的方式来自动化代码提交流程,从而检测并替换可疑代码。

NPM 安全负责人 Baldwin 在采访中说,NPM 可能会采取类似的措施,而不只是提供简单的通知。

漏洞太多,几乎每周都会出现很多新的漏洞。其中一些很快被发现,但也有一些在造成严重破坏后才成为头条新闻。

那么我们该如何降低这些风险呢?在本文中,我将介绍一些可用于保护开源依赖项的行业最佳实践。

1. 跟踪应用程序的依赖项

从逻辑上讲,随着依赖项数量的增加, 受到攻击的风险也会增加。对于直接和间接依赖项来说都是一样的 。虽然说你不可能停止使用开源软件包,但对它们进行跟踪总不是件坏事。

要查看这些依赖项十分容易, 可以在应用程序的根目录中运行 npm ls 。你可以使用 -prod 参数显示所有的生产依赖项,或使用 -long 参数显示每个包的描述摘要。

此外,你也可以使用服务来自动化依赖项管理过程, 为你的依赖项提供实时的监控和自动更新测试。一些常见的工具包括 GreenKeeper、Libraries.io 等。这些工具会整理依赖项列表并跟踪它们的相关信息。

2. 移除不需要的包

随着时间的推移和代码的不断变更,你可能会停止使用某些软件包,然后 添加新的包,但可能不会去删除旧包。

随着时间的推移,你的项目可能会积累大量不使用的依赖项。虽然这不会导致 直接的安全风险,但这些依赖项肯定会增加项目的攻击表面,并导致不必要的代码混乱。攻击者可能通过加载具有较高漏洞商数的旧包来查找漏洞,从而增加造成潜在破坏的可能性。

那么该如何检查这些不使用的依赖项?你可以使用 depcheck 来完成这项任务。depcheck 会扫描整个代码库,尝试查找 require 和 import 命令。然后,它将这些命令与已安装的软件包或 package.json 中提到的软件包相关联,并为你提供分析报告。这个命令也提供了不同的参数选项,让自动检查不使用的依赖项变得更加简单。

安装 depcheck:

npm install -g depcheck

3. 查找并修复关键安全漏洞

上面讨论的所有要点主要涉及可能会遇到的潜在风险,但那些你正在使用的依赖项呢?

最近的一项研究表明,当前有近 15%的软件包包含已知漏洞,无论是组件还是依赖项。但是,好消息是,你可以使用很多工具来分析代码并发现项目中存在的开源安全风险。

最方便的工具是 npm audit。audit 是随 npm 6 一起发布的一个脚本。npm audit 最初是由 Node Security Platform 开发的,后来放在了 npm registry 中。下面是 npm audit 官方博客的一段描述:

安全审计是对软件包依赖项安全漏洞的评估,可帮助你查找和修复依赖项中的已知漏洞,从而达到保护软件包的用户的目的。npm audit 命令会将的依赖项的描述提交到默认 registry,并要求提供已知漏洞的报告。

生成的报告通常包含以下详细信息:受影响的程序包名称、漏洞严重性和描述、路径和其他信息,以及用于修复问题的补丁命令(如果有)。你甚至可以通过运行 npm audit --json 来获取 JSON 格式的审计报告。

除此之外,npm 还提供了根据报告采取行动的建议。你可以使用 npm audit fix 来修复已经找到的问题。这些修复通常使用引导式升级或开源补丁来完成。

4. 使用内部替代方案替换过期的库

开源安全的概念在很大程度上依赖于有多少双眼睛在盯着特定的库 。越是使用广泛的软件包就越是受到密切的关注。因此,开发人员更有可能解决这些特定包中的已知安全问题。

我们来举个例子。在 GitHub 上,有很多 JSON web 令牌实现可以与 Node.js 库一起使用。但那些没有活跃维护者的库可能包含严重的漏洞。Auth0 就报告了一个这样的漏洞,任何人都可以使用任意有效负载创建自己的“签名”令牌。

如果一个很受欢迎的软件包有这样的漏洞,被开发人员发现和修补的几率会更高。但是一个不活跃甚至被遗弃的项目呢?

5. 始终选择有人在维护的库

判断一个特定包是否活跃最快最有效的方法可能是在 npm 上检查其下载量。你可以在 npm 的包主面的 Stats 里找到它。也可以使用 npm stats API 自动提取这些数字或浏览 npm-stat.com 上的历史统计数据 。对于具有 GitHub 存储库的软件包,应该查看提交历史记录、问题跟踪器以及库的相关拉取请求。

6. 经常更新依赖项

bug 和安全漏洞会不断出现,在大多数情况下,它们会立即得到修复。

我们以 2016 年初在 HMAC 软件包 hawk 中出现的正则表达式拒绝服务(ReDoS)漏洞为例。hawk 的这个 bug 很快得到修复,但仅限于最新的 4.x 版本,而像 3.x 这样的旧版本在很长一段时间后才打上补丁 。

因此,一般来说,如果使用最新可用的依赖项版本,就不太可能存在安全问题。

判断你是否正在使用最新版本依赖项的最简单方法是使用 npm outdated 命令。这个命令支持是要 -prod 标志来忽略开发依赖项,而是要—json 参数会让自动化变得更简单。

定期检查你的依赖项, 验证它们的修改日期,你可以通过 npm UI 或运行 npm view time.modified 命令来检查依赖项的最后修改日期。

结论

保护应用程序的关键是形成从一开始就将安全放在第一位的文化。在这篇文章中,我们介绍了一些用于提高 JavaScript 组件安全性的标准实践。

  • 选择有人在维护的开源依赖项。

  • 更新和监控你的组件。

  • 检查你的代码并编写测试。

  • 删除不需要的依赖项或使用替代项。

  • 使用 npm audit 等安全工具来分析你的依赖项。

  工具链接:

GreenKeeper:https://github.com/greenkeeperio/greenkeeper

Libraries.io:https://github.com/librariesio

  英文原文

https://code.tutsplus.com/articles/how-secure-are-your-javascript-open-source-dependencies--cms-31685

  课程推荐

从 Facebook、Oracle、京东等头部大厂看进阶中高级程序员,你还差点什么?许多程序员所做的业务仅仅是功能上的实现,完全不会遇到诸如“双十一”、“六一八”的高并发量挑战。那没有身处大型互联网公司就没有机会了?当然不,我们可以通过一些 BATJ 大牛的技术分享,学习到这些大型项目的设计和优化经验。

 
前端之巅 更多文章 Angular的这10个特性,你可能不知道 2018年,你需要了解这些React Native组件库 以Vue为例,解释JavaScript的反应性 我们用Flutter重写了一个React Native应用 如何构建无渲染Vue组件?
猜您喜欢 【传送门】机器视觉实战训练营昨日开营 首批优选实战材料已开源 沃尔玛宣战亚马逊,33亿美元收购电商Jet.com Ruby 之父:Ruby3 有望 3 倍提速,不添加类型推断 趣图:IT招聘会上他问"当初为什么选择PHP?" 请在约炮的时候选择通信