将Node.js应用安全和可观察性纳入IDE的插件
Liran Tal 2021年8月23日
作为开发者,我们花了很多时间在IDE中编写新代码、重构代码、添加测试、修复错误等等。近年来,IDE已经成为强大的工具,帮助我们这些开发者完成从与HTTP请求交互到普遍提高生产力的任何工作。因此,你不得不问--如果我们也能在发货前防止代码中的安全问题呢?如果我们能在集成开发环境中对我们生产的应用程序内部发生的事情进行代码级的可视性,那会怎么样?
这就是 "开发者优先 "类工具的神奇之处。有了适合你的IDE的插件,可观察性和安全性就可以直接建立在开发人员的日常工作流程中--在那里是最有效的。
在这篇博文中,我们将看一下以下内容。
- 如何在IDE中获得对数据结构的实时代码级观察能力
- 如何在生产的Node.js应用程序中找到有害的用户输入
- 如何在你的代码和开源依赖中找到并修复安全问题
如何在你的IDE中获得实时应用观察能力
以下是你需要跟随本帖的内容。
- IntelliJ IDEA(Lightrun对Visual Studio Code的支持即将推出--在此注册测试版,以先获得该支持!)
- 一个Lightrun账户和Lightrun的IntelliJ插件和Node.js代理(目前仍处于测试阶段
一旦IntelliJ IDEA插件安装完毕,点击注册按钮,它将带你通过浏览器完成一个无缝的注册过程。

接下来,我们需要为Node.js应用程序安装和配置Lightrun Node.js代理。你会在注册过程中看到说明,但如果你错过了,这里又有说明。
- 通过运行在我们的项目文件夹中安装Lightrun代理。
npm install lightrun - 在我们的Node.js应用程序代码库的开头,就在app.js文件的输入代码处实例化Lightrun代理,如下所示(在注册过程中,你会在屏幕上看到
<YOUR-COMPANY-NAME>和<YOUR-COMPANY-SECRET>值)。
require('lightrun').start({
company: '<YOUR-COMPANY-NAME>',
apiEndpoint: 'app.lightrun.com',
lightrunSecret: '<YOUR-COMPANY-SECRET>',
caPath: '',
});
如果我不在代码中叫出秘密,我就不公正了,所以一旦你达到这一点,我想指出的第一件事就是更新那行代码,以lightrunSecret 。
lightrunSecret: process.env.LIGHTRUN_API_KEY
然后当你在本地启动应用程序时,记得首先使这个环境变量可用。如果你从命令行运行应用程序,你可以这样做。
export LIGHTRUN_API_KEY=<YOUR-COMPANY-SECRET>
npm run start
**注意:**你只需要运行一次导出命令,只要你继续使用同一个终端shell会话,它就会在你的终端shell中可用。
一旦你启动应用程序,你会在右侧栏上注意到Lightrun插件现在既配置好又连接好了,你可以从你的机器名称的注释中看出(我的是 "Lirans-MBP")。
如何在一个生产型Node.js应用程序中找到有害的用户输入
我们要实验的Node.js应用程序是Snyk的Goof TODO应用程序,它是一个端到端的JavaScript和Node.js待办事项记录应用程序。
你可以通过克隆GitHub项目来抓取它的副本,并按照常见的npm项目安装说明的依赖性来开始使用。注意,它还需要一个MongoDB数据库,以便在它启动时连接到。
一旦你有了它并运行,它应该看起来像下面的截图。你会发现这个应用程序有一个有趣的功能。如果我给它发送一个todo字符串,如Get my app secured in 15 minutes 。 它将使用开源的humanize-ms npm包,将这些15 minutes 的文本转化为格式化的[15m] 的文本风格。humanize-ms包每周大约有450万次下载,所以它似乎是一个不错的选择。
现在,如果你是一个有安全意识的人,并且在过去做了一些后端应用开发,你可能会确保输入遵守一些验证和预期模式。
然而,这个东西现在正在生产中运行,虽然我不确定它得到的是什么样的用户输入,但我不想破坏任何功能。也就是说,我确实想对它可能收到的潜在危险的用户输入有一些了解。这就是Lightrun的闪光之处。
我想捕捉警报,以防有人发送文本超过10,000个字符的用户输入。为了做到这一点,我将在IntelliJ中添加一个Lightrun日志,并在解析用户输入文本的代码行中设置一个条件。它看起来像这样。
要做到这一点,当你右键单击该行代码时,选择该日志类型的注释,并按如下方式设置日志规则。item.length>10000
这基本上建立了我所说的警报,现在在我的实时运行的Node.js应用程序中设置了警报,这样,任何请求进入这个代码路径,并触发任何输入长度大于10,000字符的条件。
一旦我把Action放进去,我就会在这行代码上得到这个漂亮的小注解,还有添加它的用户。这是一个吸引注意力的好方法,为那些负责技术债务和未来重构的开发人员提供有价值的信息。
从IDE中添加一个警报是很好的,但你知道是什么让它变得更棒吗?能够在IDE控制台中直接查看这些警报,而不是打开一个新的网页来浏览日志。
要实现这个神奇的效果,请到Lightrun插件的右侧边栏,在代理条目上点击最右边的PIPE图标。然后,点击 "两者"按钮。这意味着现在警报日志将被发送到Lightrun SaaS应用程序,以及直接进入我的IDE Lightrun控制台窗口。耶!
现在我们有一个警报设置,让我们试验一下发送一些大的有效载荷。为了发送这些有效载荷,我将利用我所掌握的一些方便的命令行工具。
有了这些,我将使用以下命令发送有效载荷。
echo 'content=Buy milk in 'seq -s "" -f "5" 60000 'minutes' | http --form https://localhost:3001/create -v
这就创建了todo文本Buy milk in 500000... minutes ,数字5 ,后面有一些额外的60000个零,这是一个相当大的字符串。
在应用程序界面中,这看起来如下。
正如你所看到的,应用程序没有崩溃,MongoDB数据库也没有崩溃,似乎整体的副作用是,humanize-ms npm包简单地将该时间解析为Infinity这个词。总的来说,这很合理,并不是一个实际的问题。看起来是这样。
还记得吗,我们在IDE中为它设置了一个警报?
让我们看看那是什么样子的...
你看到Lightrun控制台窗口中突出显示的那一行吗?我们得到了符合HTTP请求的记录条件的警报,该请求被发送到一个正在运行的应用程序,就在IDE中。这很好(也很有帮助!)。
但是,这个警报有什么大惊小怪的?请跟随...
如何发现并修复你的代码和开源依赖中的安全问题
所以,很明显,那个版本的humanize-ms npm包,有一些间接的安全漏洞。每周4,500,000次的下载量是误导性的!该包的安全漏洞对任何Node.js网络应用来说,都可能是相当具有破坏性的。
我怎么知道的呢?因为我安装了Snyk IntelliJ插件,我让它扫描我的项目,它发现了这个和其他一些漏洞。让我们来看看如何运行扫描,以及使用Lightrun中的大型用户输入有效载荷警报,这个安全漏洞有多重要。
一旦你安装了Snyk IntelliJ插件并通过了认证(见这个如何安装插件的步骤指南),点击Snyk插件窗口上的绿色播放按钮来启动安全扫描。
扫描的结果将是针对以下潜在的安全问题。
- 你的第三方开源库的安全漏洞,比如那些你导入到代码库的npm包。如果你扫描的是其他语言的项目,如Java、Ruby、Python之类的,Snyk会自动拾取包的清单文件,并对它们进行扫描。
- 在你自己的代码中编码安全问题,目前支持JavaScript、TypeScript、Java和Python。
下面是Snyk开源安全扫描结果,我把第三方npm包作为依赖项添加到这个TODO项目中。
滚动浏览这些结果,你可以看到这个TODO应用程序有相当多的安全漏洞。这是个故意有漏洞的应用程序,所以我们可以演示、练习和学习这些漏洞以及如何修复它们。
还记得,我们的humanize-ms npm包来解析和格式化时间字符串吗?显然,它带来了一个正则表达式拒绝服务漏洞(ReDOS),因为它依赖于流行的ms npm包的一个脆弱版本范围。
让我们回到我们的安全漏洞有效载荷,再看一下它。
echo 'content=Buy milk in 'seq -s "" -f "5" 60000 'minutes' | http --form https://localhost:3001/create -v
正如你所记得的,当我们运行这个命令时,它发送了一个很长的字符串作为一个todo项目,但从我们可以看出,它并没有造成任何形式的拒绝服务。该应用程序正在持续地处理正常的请求,而且Node.js应用程序几乎立即发送了一个响应回来。
然而,正则表达式是......棘手的。如果它们写得不正确,它们可能会受到灾难性回溯的影响,这基本上意味着对于线性输入,它将需要超线性的时间来计算。
为了有效地攻击这个应用程序,我唯一需要改变的是将minutes 这个词重命名为minutea ,然后发送命令。为了向你展示之前和之后的情况,请看这张截图,我还没有发送请求,而htop 命令显示我的笔记本电脑中的正常CPU活动。
我预计ReDOS漏洞会发生的情况是,Node.js应用程序将花费相当多的时间来计算重码,由于Node.js架构的单线程性质,所有后续的请求都会停滞。CPU将激增到100%,因为它消耗了所有可用的资源来计算词组,但却徒劳无功。
让我们发送我们的ReDOS漏洞有效载荷。
echo 'content=Buy milk in 'seq -s "" -f "5" 60000 'minutea' | http --form https://localhost:3001/create -v
看哪!右上角的终端屏幕显示了发送的HTTP请求,没有立即响应,左下角的终端屏幕显示了Node.js进程作为绿色突出显示的条目位于表格顶部,CPU资源消耗量为98.4%。
接下来当然是修复这个和其他我的安全问题。一旦你把你的项目导入Snyk应用程序,它将在后台持续扫描和监控它们。它还会自动向你的Git仓库(无论是在GitHub上还是在其他地方)提出拉动请求,以升级项目中的脆弱版本。关于这一点,请看开始使用Snyk开源的文章。
开发者优先的安全和可观察性
以Lightrun和Snyk为代表的开发者优先工具,通过将数据带给开发者,而不是将他们带离工作流程,帮助他们在日常的开发体验中提高生产力。
在IntelliJ IDE或命令行中利用可观察性和安全性,可以帮助开发人员监控实时流量,并在安全问题到达持续集成服务器之前发现和修复这些问题,更不用说生产。
为了让你开始使用这两者,请看以下资源。
注册Snyk
使用Snyk免费保护你的代码、依赖关系、容器和IaC。
加入我们2021年的SnykCon
我们将在为期3天的免费虚拟活动中把开发和安全结合起来,专注于帮助团队安全地构建。