api节点_入侵节点js旧版网址api

api节点

How to bypass hostname verification to exploit allowlist functions

如何绕过主机名验证以利用允许列表功能

介绍 (Introduction)

Security is essential to us in Kiwi.com as it ensures our customers’ safety. We need to be proactive and search for possible security issues that might affect our business and potentially cause a loss of customers’ trust.

Kiwi.com中的安全性对我们至关重要,因为它可以确保客户的安全。 我们需要积极主动,寻找可能影响我们业务并可能导致失去客户信任的安全问题。

Our security engineers ensure the highest possible safety of our services. Their weapon of choice? Penetration testing. It is a simulation of a cyber-attack conducted by authorized developers to discover and penetrate any security vulnerabilities in the system/app/service the team is developing. Other proactive steps include secure code review, dependency scanning, SAST, and asset monitoring.

我们的安全工程师确保我们服务的最高安全性。 他们选择的武器? 渗透测试。 这是对授权开发人员进行的网络攻击的模拟,以发现并渗透团队正在开发的系统/应用程序/服务中的任何安全漏洞。 其他主动步骤包括安全代码审查,依赖项扫描,SAST和资产监视。

Sometimes the security issue can be discovered even in a service we use often. Node.js sits behind most of our frontends, interacting with other backends, and recently a very interesting vulnerability was found just within its URL API. Node.js is a very vast project, which unfortunately comes in hand with some of its parts turning into a legacy. If the issue hasn’t been encountered, it would have caused serious security problems. Attackers could have exploited how Node.js processes hostname, making it easy for them to bypass security checks and obtain access to the customer’s accounts. Luckily, our application security team discovered the issue before it could cause us any harm.

有时即使在我们经常使用的服务中也可能发现安全问题。 Node.js位于我们大多数前端的后面,并与其他后端交互,最近在URL API中发现了一个非常有趣的漏洞。 Node.js是一个非常庞大的项目,不幸的是,它的某些部分已成为遗产。 如果未遇到此问题,则将导致严重的安全问题。 攻击者可能已经利用Node.js如何处理主机名,从而使他们轻松绕过安全检查并获得对客户帐户的访问权限。 幸运的是,我们的应用程序安全团队在可能对我们造成任何危害之前就发现了该问题。

In this article, you will learn how our security engineers found these particular security issues and how they mitigated them to ensure as high security for our customers as possible.

在本文中,您将学习我们的安全工程师如何发现这些特殊的安全问题,以及如何缓解这些问题,以确保为我们的客户提供尽可能高的安全性。

Let me share the findings with you.

让我与您分享调查结果。

Node.js的URL解析API入门 (A small primer on Node.js’s URL parsing APIs)

First of all, we should get familiar with URL parsing APIs in Node.js. Looking at the currently available docs (Node.js v13.8.0 Documentation), we can see that the URL module provides utilities for URL resolution and parsing. It can be accessed using:

首先,我们应该熟悉Node.js中的URL解析API。 查看当前可用的文档(Node.js v13.8.0文档),我们可以看到URL模块提供了用于URL解析和解析的实用程序。 可以使用以下命令访问它:

const url = require(‘url’);

const url = require('url');

“The URL module provides two APIs for working with URLs: a legacy API that is Node.js specific, and a newer API that implements the same WHATWG URL Standard used by web browsers”, as stated in the docs.

如文档所述,“ URL模块提供了两个用于处理URL的API:一个特定于Node.js的旧API,以及一个实现与Web浏览器所使用的WHATWG URL标准相同的更新API”。

URL parsing is frequently used in allowlist/denylist functions to prevent various attack vectors. For example, checking the hostname of a given URL against a list of allowed origins, to prevent for example Open Redirect vulnerabilities.

URL解析经常在允许列表/拒绝列表功能中使用,以防止各种攻击媒介。 例如,对照允许的来源列表检查给定URL的主机名,以防止例如“打开重定向”漏洞。

Using Node.js’ URL module, you can use url.host and url.hostname functions, the main difference is that url.hostname does not include the port.

使用Node.js的URL模块,可以使用url.host和url.hostname函数,主要区别在于url.hostname不包含端口。

Usage:

用法:

Image for post
https://nodejs.org/docs/latest/api/url.html#url_url_hostnamehttps://nodejs.org/docs/latest/api/url.html#url_url_hostname

But there is also Legacy URL API, deprecated since v11.0.0:

但是还有自v11.0.0起不推荐使用的旧版URL API:

The legacy urlObject (require(‘url’).Url) is created and returned by the url.parse() function.

旧版urlObject(require('url')。Url)由url.parse()函数创建并返回。

Image for post
https://nodejs.org/docs/latest/api/url.html#url_legacy_url_api https://nodejs.org/docs/latest/api/url.html#url_legacy_url_api

If we compare both WHATWG and Legacy URL API, functionality, and results from the security point of view should be the same, but what could go wrong?

如果我们同时比较WHATWG和传统URL API,则从安全性角度来看,功能和结果应该相同,但是可能出什么问题?

允许的域-测试方法 (Allowed domains — testing methodology)

We have implemented various server-side security checks. One of them is a function for allowed domains: requests from the frontend can only reach API endpoints on a server with an allowed hostname, in our case anything hosted on the *.kiwi.com:

我们已经实现了各种服务器端安全检查。 其中之一是用于允许的域的功能:来自前端的请求只能到达具有允许的主机名的服务器上的API端点,在我们的情况下,该请求可以托管在* .kiwi.com上:

Image for post
A snippet of allowlist function for allowed hostnames
允许的主机名的allowlist函数的摘要

Even though your own security precautions can be solid, the vulnerability can be in the tools that you use. The Node.js URL API was used for the allowlist function, and it turned out that even if you do everything according to the documentation, you can still be vulnerable.

即使您自己的安全预防措施很可靠,该漏洞也可能存在于您使用的工具中。 Node.js URL API用于allowlist函数,事实证明,即使根据文档进行了所有操作,您仍然容易受到攻击。

Allowlist/denylist functions are usually an interesting scope for penetration testers, as there are a lot of things that could go wrong. Bypassing such security checks could often lead to SSRF or open redirect vulnerabilities.

对于渗透测试人员来说,Allowlist / denylist函数通常是一个有趣的范围,因为可能会出错。 绕过此类安全检查通常可能会导致SSRF或开放的重定向漏洞。

The workflow of testing such attack vectors might look like this:

测试此类攻击媒介的工作流程可能如下所示:

Let’s say you have a parameter named “allowed-subdomain”, when passing any URL into it, the function will check the hostname and verify if the domain or subdomain is allowed to communicate with kiwi.com services.

假设您有一个名为“ allowed-subdomain ”的参数,当向其中传递任何URL时,该函数将检查主机名并验证是否允许该域或子域与kiwi.com服务进行通信。

https://www.kiwi.com/?allowed-subdomain=test.kiwi.com

https://www.kiwi.com/?allowed-subdomain=test.kiwi.com

  • Allowlist check passed, communication with “test.kiwi.com” allowed

    通过了 允许 清单 检查 ,允许与“ test.kiwi.com”进行通信

https://www.kiwi.com/?allowed-subdomain=attacker.com

https://www.kiwi.com/?allowed-subdomain=attacker.com

  • Allowlist check refused, communication with “attacker.com” denied

    拒绝 允许清单 检查,拒绝 与“ attacker.com”的通信

Some of the steps that attack might try to bypass the check includes changing URL schema, prefix, infix, and suffix to bypass allowlist.

攻击者可能尝试绕过检查的一些步骤包括更改URL架构,前缀,中缀和后缀以绕过允许列表。

None of the above worked, but during bug bounty/penetration testing, persistence is the key. You can even automate the testing with some tool and try fuzzing it with a list of most common bypass payloads. There is a lot of possibilities, to have some idea, you can check the following links:

以上方法均无效,但是在漏洞赏金/渗透测试期间,持久性是关键。 您甚至可以使用某些工具使测试自动化,并尝试使用最常见的旁路有效负载列表对其进行模糊测试。 有很多可能,如果您有想法,可以检查以下链接:

I would also highly recommend checking “A New Era of SSRF -Exploiting URL Parser in Trending Programming Languages!” talk from Orange Tsai, which was presented on the Black Hat USA 2017 conference.

我还强烈建议选中“ SSRF的新时代-趋势编程语言中的URL解析器开发! ”来自蔡康宁(Orange Tsai)的演讲,该演讲已在“美国黑帽(Black Hat)” 2017年会议上发表。

那CRLF注射呢? (What about CRLF Injection?)

The term CRLF refers to Carriage Return (ASCII 13, \r) Line Feed (ASCII 10, \n). They’re used to note the termination of a line. A CRLF Injection attack occurs when a user manages to submit a CRLF into an application.

术语CRLF表示回车(ASCII 13,\ r)换行(ASCII 10,\ n)。 它们用于记录行的终止。 当用户设法将CRLF提交到应用程序时,就会发生CRLF注入攻击。

Appending %0A%0D (\r\n) after the domain name:

在域名后附加%0A%0D(\ r \ n):

Gotcha! We tricked the allowlist function and a domain “kiwi.comevil.com” was returned as hostname with access allowed. Attackers with possession of the “comevil.com” domain could use this for malicious purposes.

知道了! 我们欺骗了allowlist函数,并以允许访问的主机名返回域“ kiwi.comevil.com”。 拥有“ comevil.com”域的攻击者可以将其用于恶意目的。

影响-Kiwi.com可能出什么问题 (Impact — what could go wrong in Kiwi.com)

This was easy to exploit the vulnerability with a significant impact on our users. An attacker could use the knowledge of such allowlist bypass in various ways. One of them was tricking the debug feature to override the GraphQL server address used for authentication.

这很容易利用该漏洞,对我们的用户产生重大影响。 攻击者可以各种方式使用这种允许列表绕过的知识。 其中之一是欺骗调试功能以覆盖用于身份验证的GraphQL服务器地址。

For the victim, the functionality of Kiwi.com changed dramatically, as any of the future requests from the browser would go to the malicious server. This means that when the victim tried to log-in into his/her account, the credentials were sent to the attackers’ controlled domain (kiwi.comevil.com), instead of the official Kiwi.com GraphQL server.

对于受害者而言,Kiwi.com的功能发生了巨大变化,因为将来来自浏览器的任何请求都将发送到恶意服务器。 这意味着,当受害者尝试登录其帐户时,会将凭据发送到攻击者的控制域(kiwi.comevil.com),而不是官方的Kiwi.com GraphQL服务器。

安全的代码审查-根本原因发现 (Secure code review — root cause discovery)

This was a white-box penetration test. Bypassing the allowlist function was an easy part, now we had to find a vulnerable code, determine the root cause, and propose a mitigation/fix.

这是白盒渗透测试。 绕过allowlist函数是一个简单的步骤,现在我们必须找到一个易受攻击的代码,确定根本原因,并提出缓解措施/解决方案。

With other members of the AppSec team, we quickly determined that the allowlist function is written correctly, but the validation problem was underlying in the Node.js module.

与AppSec团队的其他成员一起,我们Swift确定allowlist函数编写正确,但是验证问题是Node.js模块中的基础。

Image for post
Proof of Concept code
概念证明代码

As you can see in the screenshot above, the legacy URL API is vulnerable, but the new API is correctly parsing the hostname as it should be, based on the RFC.

从上面的屏幕快照中可以看到,旧的URL API容易受到攻击,但是新的API可以根据RFC正确地解析主机名。

At the time, we were using the core url.parse() method to verify the hostname. We looked up the documentation and learned that the URL API is legacy and is deprecated.

当时,我们使用核心url.parse()方法来验证主机名。 我们查阅了文档 ,了解到URL API是旧版并且已弃用。

But we weren’t able to find any security advisory warning about the CRLF vulnerability in a hostname parser.

但是我们无法在主机名解析器中找到有关CRLF漏洞的任何安全建议警告。

We weren’t exactly sure if this is a 0day exploit or not, so I reported it to the Node.js bug bounty program just to be sure. https://hackerone.com/reports/771596 Interesting thing is that another member of our AppSec team found a vulnerability in the same module a year ago: https://hackerone.com/reports/395845.

我们不确定这是否是0day漏洞利用,因此为了确定,我将其报告给Node.js错误赏金计划。 https://hackerone.com/reports/771596有趣的是,一年前,我们AppSec团队的另一位成员在同一模块中发现了一个漏洞: https : //hackerone.com/reports/395845

The Node.js team responded that there are known security issues in URL API and as it’s considered legacy now, they are not planning to fix them. Fair enough, but it’s reasonable to assume that a lot of companies are still using it and there should be more security warnings.

Node.js团队回应说,URL API中存在已知的安全问题,并且由于现在已被认为是旧问题,因此他们不打算对其进行修复。 足够公平,但可以合理地假设许多公司仍在使用它,并且应该有更多的安全警告。

结论–在那里安全 (Conclusion — stay safe out there)

Best effort URL-parsing libraries are not a good choice for security controls, it is highly recommended to add additional checks to be sure that critical functionality is properly hardened.

尽力而为URL解析库不是用于安全控件的理想选择,强烈建议添加其他检查以确保正确强化了关键功能。

Based on our findings we could conclude that once you are using Node.js, you should do some static code analysis/dependency scanning (ESLint) to determine if your codebase is relying on the legacy URL API.

根据我们的发现,我们可以得出结论,一旦您使用Node.js,就应该进行一些静态代码分析/依赖性扫描(ESLint),以确定您的代码库是否依赖于旧版URL API。

Example of ESLint rule:

ESLint规则示例:

"rules": {
// Forbid import of legacy URL API
"no-restricted-imports": [
"error",
{
"name": "url",
"message": "Please use built-in URL",
},
],
},

At Kiwi.com we are using “The Zoo” service registry https://github.com/kiwicom/the-zoo for all our Gitlab repositories. It is an open-source project developed by our engineers who are always looking for the best available solutions and being proactive in the sense of innovation. This tool allows us to write a quick check, scan all our projects/repositories, and automatically create issues with the description for our developers or even the merge requests with the correct patch.

在Kiwi.com,我们为所有Gitlab存储库使用“动物园”服务注册表https://github.com/kiwicom/the-zoo 。 这是一个由我们的工程师开发的开源项目,这些工程师一直在寻找最佳的可用解决方案,并积极主动地进行创新。 使用此工具,我们可以进行快速检查,扫描所有项目/存储库,并自动为开发人员创建描述问题,甚至自动创建带有正确补丁的合并请求。

We also found some repositories from top companies on GitHub with the same or similar issues, so we are in the process of writing a CodeQL query to find most of them and to properly notify them about the potential security vulnerabilities.

我们还从GitHub上的顶级公司中找到了一些存在相同或相似问题的存储库,因此我们正在编写CodeQL查询以查找其中的大多数存储库,并适当地通知他们潜在的安全漏洞。

Did you find this article interesting or can you even see yourself conducting similar work? Let us know about it! We can offer plenty of opportunities for people who are willing to make a change in the technical world and strongly support those who come up with any innovative ideas. You can find us at many online conferences and meetups across the world even in these hard times and talk to us there or approach us right away via our HR portal with vacancies waiting for you!

您觉得这篇文章有趣吗,或者甚至看到自己在从事类似的工作? 让我们了解一下! 我们愿意为愿意在技术领域做出改变并强烈支持提出任何创新想法的人们提供大量机会。 即使在这样的困难时期,您也可以在世界各地的许多在线会议和聚会上找到我们,并在那里与我们交谈或通过我们的人力资源门户网站与我们联系,职位空缺正等着您!

翻译自: https://code.kiwi.com/hacking-node-js-legacy-url-api-38208f9dc3f5

api节点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值