diff --git a/plugins/wasm-cpp/extensions/custom_response/README_EN.md b/plugins/wasm-cpp/extensions/custom_response/README_EN.md index 929c03f14..6d6e07a12 100644 --- a/plugins/wasm-cpp/extensions/custom_response/README_EN.md +++ b/plugins/wasm-cpp/extensions/custom_response/README_EN.md @@ -3,7 +3,7 @@

# Description -`custom-response` plugin supports configure custom responses, including custom HTTP response status codes, HTTP response headers and HTTP response body, which can be used in the scenarios of response mocking and sending a custom response for specific status codes, such as customizing the response for rate-limited requests. +`custom-response` plugin implements a function of sending custom responses, including custom HTTP response status codes, HTTP response headers and HTTP response body, which can be used in the scenarios of response mocking and sending a custom response for specific status codes, such as customizing the response for rate-limited requests. # Configuration Fields diff --git a/plugins/wasm-cpp/extensions/request_block/README.md b/plugins/wasm-cpp/extensions/request_block/README.md index d334aacd0..167ffc890 100644 --- a/plugins/wasm-cpp/extensions/request_block/README.md +++ b/plugins/wasm-cpp/extensions/request_block/README.md @@ -1,3 +1,7 @@ +

+ English | 中文 +

+ # 功能说明 `request-block`插件实现了基于 URL、请求头等特征屏蔽 HTTP 请求,可以用于防护部分站点资源不对外部暴露 @@ -5,9 +9,9 @@ | 名称 | 数据类型 | 填写要求 | 默认值 | 描述 | | -------- | -------- | -------- | -------- | -------- | -| block_urls | array of string | 选填,`block_urls`,`block_headers`,`block_bodys` 中至少必填一项 | - | 配置用于匹配需要屏蔽 URL 的字符串 | -| block_headers | array of string | 选填,`block_urls`,`block_headers`,`block_bodys` 中至少必填一项 | - | 配置用于匹配需要屏蔽请求 Header 的字符串 | -| block_bodys | array of string | 选填,`block_urls`,`block_headers`,`block_bodys` 中至少必填一项 | - | 配置用于匹配需要屏蔽请求 Body 的字符串 | +| block_urls | array of string | 选填,`block_urls`,`block_headers`,`block_bodies` 中至少必填一项 | - | 配置用于匹配需要屏蔽 URL 的字符串 | +| block_headers | array of string | 选填,`block_urls`,`block_headers`,`block_bodies` 中至少必填一项 | - | 配置用于匹配需要屏蔽请求 Header 的字符串 | +| block_bodies | array of string | 选填,`block_urls`,`block_headers`,`block_bodies` 中至少必填一项 | - | 配置用于匹配需要屏蔽请求 Body 的字符串 | | blocked_code | number | 选填 | 403 | 配置请求被屏蔽时返回的 HTTP 状态码 | | blocked_message | string | 选填 | - | 配置请求被屏蔽时返回的 HTTP 应答 Body | | case_sensitive | bool | 选填 | true | 配置匹配时是否区分大小写,默认区分 | @@ -45,7 +49,7 @@ curl http://exmaple.com -H 'my-header: example-value' ## 屏蔽请求 body ```yaml -block_bodys: +block_bodies: - "hello world" case_sensitive: false ``` @@ -65,7 +69,7 @@ _rules_: - _match_route_: - route-a - route-b - block_bodys: + block_bodies: - "hello world" # 规则二:按域名匹配生效 - _match_domain_: @@ -73,7 +77,7 @@ _rules_: - test.com block_urls: - "swagger.html" - block_bodys: + block_bodies: - "hello world" ``` 此例 `_match_route_` 中指定的 `route-a` 和 `route-b` 即在创建网关路由时填写的路由名称,当匹配到这两个路由时,将使用此段配置; @@ -82,5 +86,5 @@ _rules_: # 请求 Body 大小限制 -当配置了 `block_bodys` 时,仅支持小于 32 MB 的请求 Body 进行匹配。若请求 Body 大于此限制,并且不存在匹配到的 `block_urls` 和 `block_headers` 项时,不会对该请求执行屏蔽操作 -当配置了 `block_bodys` 时,若请求 Body 超过全局配置 DownstreamConnectionBufferLimits,将返回 `413 Payload Too Large` +当配置了 `block_bodies` 时,仅支持小于 32 MB 的请求 Body 进行匹配。若请求 Body 大于此限制,并且不存在匹配到的 `block_urls` 和 `block_headers` 项时,不会对该请求执行屏蔽操作 +当配置了 `block_bodies` 时,若请求 Body 超过全局配置 DownstreamConnectionBufferLimits,将返回 `413 Payload Too Large` diff --git a/plugins/wasm-cpp/extensions/request_block/README_EN.md b/plugins/wasm-cpp/extensions/request_block/README_EN.md new file mode 100644 index 000000000..01df5afe8 --- /dev/null +++ b/plugins/wasm-cpp/extensions/request_block/README_EN.md @@ -0,0 +1,90 @@ +

+ English | 中文 +

+ +# Description +`request-block` plugin implements a request blocking function based on request characteristics such as URL and request header. It can be used to protect internal resources from unauthorized access. + +# Configuration Fields + +| Name | Type | Requirement | Default Value | Description | +| -------- | -------- | -------- | -------- | -------- | +| block_urls | array of string | Optional. Choose one from following: `block_urls`, `block_headers`, `block_bodies` | - | HTTP URLs to be blocked. | +| block_headers | array of string | Optional. Choose one from following: `block_urls`, `block_headers`, `block_bodies` | - | HTTP request headers to be blocked. | +| block_bodies | array of string | Optional. Choose one from following: `block_urls` ,`block_headers`, `block_bodies` | - | HTTP request bodies to be blocked. | +| blocked_code | number | Optional | 403 | HTTP response status code to be sent when corresponding request is blocked. | +| blocked_message | string | Optional | - | HTTP response body to be sent when corresponding request is blocked. | +| case_sensitive | bool | Optional | true | Whether to use case-senstive comparison when matching. Enabled by default. | + +# Configuration Samples + +## Block Specific Request URLs +```yaml +block_urls: +- swagger.html +- foo=bar +case_sensitive: false +``` + +According to the configuration above, following requests will be blocked: + +```bash +curl http://example.com?foo=Bar +curl http://exmaple.com/Swagger.html +``` + +## Block Specific Request Headers +```yaml +block_headers: +- example-key +- example-value +``` + +According to the configuration above, following requests will be blocked: + +```bash +curl http://example.com -H 'example-key: 123' +curl http://exmaple.com -H 'my-header: example-value' +``` + +## Block Specific Request Bodies +```yaml +block_bodies: +- "hello world" +case_sensitive: false +``` + +According to the configuration above, following requests will be blocked: + +```bash +curl http://example.com -d 'Hello World' +curl http://exmaple.com -d 'hello world' +``` + +## Only Enable for Specific Routes or Domains +```yaml +# Use _rules_ field for fine-grained rule configurations +_rules_: +# Rule 1: Match by route name +- _match_route_: + - route-a + - route-b + block_bodies: + - "hello world" +# Rule 2: Match by domain +- _match_domain_: + - "*.example.com" + - test.com + block_urls: + - "swagger.html" + block_bodies: + - "hello world" +``` +In the rule sample of `_match_route_`, `route-a` and `route-b` are the route names provided when creating a new gateway route. When the current route names matches the configuration, the rule following shall be applied. +In the rule sample of `_match_domain_`, `*.example.com` and `test.com` are the domain names used for request matching. When the current domain name matches the configuration, the rule following shall be applied. +All rules shall be checked following the order of items in the `_rules_` field, The first matched rule will be applied. All remained will be ignored. + +# Maximum Request Body Size Limitation + +When `block_bodies` is configured, body matching shall only be performed when its size is smaller than 32MB. If not, and no `block_urls` or `block_headers` configuration is matched, the request won't be blocked. +When `block_bodies` is configured, if the size of request body exceeds the global configuration of DownstreamConnectionBufferLimits, a ``413 Payload Too Large`` response will be returned. \ No newline at end of file diff --git a/plugins/wasm-cpp/extensions/request_block/plugin.cc b/plugins/wasm-cpp/extensions/request_block/plugin.cc index 4339fe5c6..fbc7c5a1c 100644 --- a/plugins/wasm-cpp/extensions/request_block/plugin.cc +++ b/plugins/wasm-cpp/extensions/request_block/plugin.cc @@ -108,24 +108,24 @@ bool PluginRootContext::parsePluginConfig(const json& configuration, return false; } if (!JsonArrayIterate( - configuration, "block_bodys", [&](const json& item) -> bool { + configuration, "block_bodies", [&](const json& item) -> bool { auto body = JsonValueAs(item); if (body.second != Wasm::Common::JsonParserResultDetail::OK) { - LOG_WARN("cannot parse block_bodys"); + LOG_WARN("cannot parse block_bodies"); return false; } if (rule.case_sensitive) { - rule.block_bodys.push_back(std::move(body.first.value())); + rule.block_bodies.push_back(std::move(body.first.value())); } else { - rule.block_bodys.push_back( + rule.block_bodies.push_back( absl::AsciiStrToLower(body.first.value())); } return true; })) { - LOG_WARN("failed to parse configuration for block_bodys."); + LOG_WARN("failed to parse configuration for block_bodies."); return false; } - if (rule.block_bodys.empty() && rule.block_headers.empty() && + if (rule.block_bodies.empty() && rule.block_headers.empty() && rule.block_urls.empty()) { LOG_WARN("there is no block rules"); return false; @@ -197,7 +197,7 @@ bool PluginRootContext::checkHeader(const RequestBlockConfigRule& rule, } } } - if (!rule.block_bodys.empty()) { + if (!rule.block_bodies.empty()) { check_body = true; } return true; @@ -212,7 +212,7 @@ bool PluginRootContext::checkBody(const RequestBlockConfigRule& rule, bodystr = absl::AsciiStrToLower(request_body); body = bodystr; } - for (const auto& block_body : rule.block_bodys) { + for (const auto& block_body : rule.block_bodies) { if (absl::StrContains(body, block_body)) { sendLocalResponse(rule.blocked_code, "", rule.blocked_message, {}); return false; diff --git a/plugins/wasm-cpp/extensions/request_block/plugin.h b/plugins/wasm-cpp/extensions/request_block/plugin.h index 4c9288f2a..29f2d2f9a 100644 --- a/plugins/wasm-cpp/extensions/request_block/plugin.h +++ b/plugins/wasm-cpp/extensions/request_block/plugin.h @@ -45,7 +45,7 @@ struct RequestBlockConfigRule { bool case_sensitive = true; std::vector block_urls; std::vector block_headers; - std::vector block_bodys; + std::vector block_bodies; }; // PluginRootContext is the root context for all streams processed by the diff --git a/plugins/wasm-cpp/extensions/request_block/plugin_test.cc b/plugins/wasm-cpp/extensions/request_block/plugin_test.cc index 40cc32711..2b6dce5ae 100644 --- a/plugins/wasm-cpp/extensions/request_block/plugin_test.cc +++ b/plugins/wasm-cpp/extensions/request_block/plugin_test.cc @@ -128,7 +128,7 @@ TEST_F(RequestBlockTest, CaseSensitive) { { "block_urls": ["?foo=bar", "swagger.html"], "block_headers": ["headerKey", "headerValue"], - "block_bodys": ["Hello World"] + "block_bodies": ["Hello World"] })"; config_.set({configuration.data(), configuration.size()}); @@ -188,7 +188,7 @@ TEST_F(RequestBlockTest, CaseInsensitive) { "blocked_code": 404, "block_urls": ["?foo=bar", "swagger.html"], "block_headers": ["headerKey", "headerValue"], - "block_bodys": ["Hello World"] + "block_bodies": ["Hello World"] })"; config_.set({configuration.data(), configuration.size()}); diff --git a/plugins/wasm-go/README.md b/plugins/wasm-go/README.md index fc51b5f30..7046c9934 100644 --- a/plugins/wasm-go/README.md +++ b/plugins/wasm-go/README.md @@ -89,20 +89,20 @@ spec: - default/foo # default 命名空间下名为 foo 的 ingress 会执行下面这个配置 config: - block_bodys: + block_bodies: - "foo" - ingress: - default/bar # default 命名空间下名为 bar 的 ingress 会执行下面这个配置 config: - block_bodys: + block_bodies: - "bar" # 域名级生效配置 - domain: - "*.example.com" # 若请求匹配了上面的域名, 会执行下面这个配置 config: - block_bodys: + block_bodies: - "foo" - "bar" url: oci:///request-block:1.0.0 diff --git a/plugins/wasm-go/README_EN.md b/plugins/wasm-go/README_EN.md index da03938e6..0bf876cfe 100644 --- a/plugins/wasm-go/README_EN.md +++ b/plugins/wasm-go/README_EN.md @@ -83,20 +83,20 @@ spec: - default/foo # the ingress foo in namespace default will use this config config: - block_bodys: + block_bodies: - "foo" - ingress: - default/bar # the ingress bar in namespace default will use this config config: - block_bodys: + block_bodies: - "bar" # domain-level takes effect - domain: - "*.example.com" # if the request's domain matched, this config will be used config: - block_bodys: + block_bodies: - "foo" - "bar" url: oci:///request-block:1.0.0 diff --git a/plugins/wasm-go/extensions/request-block/README.md b/plugins/wasm-go/extensions/request-block/README.md index d334aacd0..0f4cc5e7e 100644 --- a/plugins/wasm-go/extensions/request-block/README.md +++ b/plugins/wasm-go/extensions/request-block/README.md @@ -5,9 +5,9 @@ | 名称 | 数据类型 | 填写要求 | 默认值 | 描述 | | -------- | -------- | -------- | -------- | -------- | -| block_urls | array of string | 选填,`block_urls`,`block_headers`,`block_bodys` 中至少必填一项 | - | 配置用于匹配需要屏蔽 URL 的字符串 | -| block_headers | array of string | 选填,`block_urls`,`block_headers`,`block_bodys` 中至少必填一项 | - | 配置用于匹配需要屏蔽请求 Header 的字符串 | -| block_bodys | array of string | 选填,`block_urls`,`block_headers`,`block_bodys` 中至少必填一项 | - | 配置用于匹配需要屏蔽请求 Body 的字符串 | +| block_urls | array of string | 选填,`block_urls`,`block_headers`,`block_bodies` 中至少必填一项 | - | 配置用于匹配需要屏蔽 URL 的字符串 | +| block_headers | array of string | 选填,`block_urls`,`block_headers`,`block_bodies` 中至少必填一项 | - | 配置用于匹配需要屏蔽请求 Header 的字符串 | +| block_bodies | array of string | 选填,`block_urls`,`block_headers`,`block_bodies` 中至少必填一项 | - | 配置用于匹配需要屏蔽请求 Body 的字符串 | | blocked_code | number | 选填 | 403 | 配置请求被屏蔽时返回的 HTTP 状态码 | | blocked_message | string | 选填 | - | 配置请求被屏蔽时返回的 HTTP 应答 Body | | case_sensitive | bool | 选填 | true | 配置匹配时是否区分大小写,默认区分 | @@ -45,7 +45,7 @@ curl http://exmaple.com -H 'my-header: example-value' ## 屏蔽请求 body ```yaml -block_bodys: +block_bodies: - "hello world" case_sensitive: false ``` @@ -65,7 +65,7 @@ _rules_: - _match_route_: - route-a - route-b - block_bodys: + block_bodies: - "hello world" # 规则二:按域名匹配生效 - _match_domain_: @@ -73,7 +73,7 @@ _rules_: - test.com block_urls: - "swagger.html" - block_bodys: + block_bodies: - "hello world" ``` 此例 `_match_route_` 中指定的 `route-a` 和 `route-b` 即在创建网关路由时填写的路由名称,当匹配到这两个路由时,将使用此段配置; @@ -82,5 +82,5 @@ _rules_: # 请求 Body 大小限制 -当配置了 `block_bodys` 时,仅支持小于 32 MB 的请求 Body 进行匹配。若请求 Body 大于此限制,并且不存在匹配到的 `block_urls` 和 `block_headers` 项时,不会对该请求执行屏蔽操作 -当配置了 `block_bodys` 时,若请求 Body 超过全局配置 DownstreamConnectionBufferLimits,将返回 `413 Payload Too Large` +当配置了 `block_bodies` 时,仅支持小于 32 MB 的请求 Body 进行匹配。若请求 Body 大于此限制,并且不存在匹配到的 `block_urls` 和 `block_headers` 项时,不会对该请求执行屏蔽操作 +当配置了 `block_bodies` 时,若请求 Body 超过全局配置 DownstreamConnectionBufferLimits,将返回 `413 Payload Too Large` diff --git a/plugins/wasm-go/extensions/request-block/main.go b/plugins/wasm-go/extensions/request-block/main.go index a36828411..7c378753f 100644 --- a/plugins/wasm-go/extensions/request-block/main.go +++ b/plugins/wasm-go/extensions/request-block/main.go @@ -41,7 +41,7 @@ type RequestBlockConfig struct { caseSensitive bool blockUrls []string blockHeaders []string - blockBodys []string + blockBodies []string } func parseConfig(json gjson.Result, config *RequestBlockConfig, log wrapper.Log) error { @@ -75,19 +75,19 @@ func parseConfig(json gjson.Result, config *RequestBlockConfig, log wrapper.Log) config.blockHeaders = append(config.blockHeaders, strings.ToLower(header)) } } - for _, item := range json.Get("block_bodys").Array() { + for _, item := range json.Get("block_bodies").Array() { body := item.String() if body == "" { continue } if config.caseSensitive { - config.blockBodys = append(config.blockBodys, body) + config.blockBodies = append(config.blockBodies, body) } else { - config.blockBodys = append(config.blockBodys, strings.ToLower(body)) + config.blockBodies = append(config.blockBodies, strings.ToLower(body)) } } if len(config.blockUrls) == 0 && len(config.blockHeaders) == 0 && - len(config.blockBodys) == 0 { + len(config.blockBodies) == 0 { return errors.New("there is no block rules") } return nil @@ -131,7 +131,7 @@ func onHttpRequestHeaders(ctx wrapper.HttpContext, config RequestBlockConfig, lo } } } - if len(config.blockBodys) == 0 { + if len(config.blockBodies) == 0 { ctx.DontReadRequestBody() } return types.ActionContinue @@ -142,7 +142,7 @@ func onHttpRequestBody(ctx wrapper.HttpContext, config RequestBlockConfig, body if !config.caseSensitive { bodyStr = strings.ToLower(bodyStr) } - for _, blockBody := range config.blockBodys { + for _, blockBody := range config.blockBodies { if strings.Contains(bodyStr, blockBody) { proxywasm.SendHttpResponse(config.blockedCode, nil, []byte(config.blockedMessage), -1) return types.ActionContinue diff --git a/samples/wasmplugin/ingress-level-config.yaml b/samples/wasmplugin/ingress-level-config.yaml index 1773823b8..623fb6e11 100644 --- a/samples/wasmplugin/ingress-level-config.yaml +++ b/samples/wasmplugin/ingress-level-config.yaml @@ -12,10 +12,10 @@ spec: - ingress: - default/foo config: - block_bodys: + block_bodies: - "foo" - ingress: - default/bar config: - block_bodys: + block_bodies: - "bar"