feat(uri-blocker): add custom rejected message (#4849)

This commit is contained in:
okaybase 2021-08-21 12:10:31 +08:00 committed by GitHub
parent 4e726da34d
commit effaf3c60e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 143 additions and 2 deletions

View File

@ -36,6 +36,10 @@ local schema = {
minimum = 200,
default = 403
},
rejected_msg = {
type = "string",
minLength = 1
},
},
required = {"block_rules"},
}
@ -86,6 +90,9 @@ function _M.rewrite(conf, ctx)
local from = re_find(ctx.var.request_uri, conf.block_rules_concat, "jo")
if from then
if conf.rejected_msg then
return conf.rejected_code, { error_msg = conf.rejected_msg }
end
return conf.rejected_code
end
end

View File

@ -38,7 +38,8 @@ The plugin helps we intercept user requests, we only need to indicate the `block
| Name | Type | Requirement | Default | Valid | Description |
| ------------- | ------------- | ----------- | ------- | ---------- | --------------------------------------------------------------------------- |
| block_rules | array[string] | required | | | Regular filter rule array. Each of these items is a regular rule. If the current request URI hits any one of them, set the response code to rejected_code to exit the current user request. Example: `["root.exe", "root.m+"]`. |
| rejected_code | integer | optional | 403 | [200, ...] | The HTTP status code returned when the request URI hit any of `block_rules` |
| rejected_code | integer | optional | 403 | [200, ...] | The HTTP status code returned when the request URI hit any of `block_rules`. |
| rejected_msg | string | optional | | non-empty | The HTTP response body returned when the request URI hit any of `block_rules`. |
## How To Enable
@ -76,6 +77,20 @@ Server: APISIX web server
... ...
```
If you set the property `rejected_msg` to `"access is not allowed"` , the response body will like below:
```shell
$ curl -i http://127.0.0.1:9080/root.exe?a=a
HTTP/1.1 403 Forbidden
Date: Wed, 17 Jun 2020 13:55:41 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 150
Connection: keep-alive
Server: APISIX web server
{"error_msg":"access is not allowed"}
```
## Disable Plugin
When you want to disable the `uri blocker` plugin, it is very simple, you can delete the corresponding json configuration in the plugin configuration, no need to restart the service, it will take effect immediately:

View File

@ -38,7 +38,8 @@ title: uri-blocker
| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 |
| ------------- | ------------- | ------ | ------ | ---------- | ------------------------------------------------------------------- |
| block_rules | array[string] | 必须 | | | 正则过滤数组。它们都是正则规则,如果当前请求 URI 命中任何一个,请将响应代码设置为 rejected_code 以退出当前用户请求。例如: `["root.exe", "root.m+"]`。 |
| rejected_code | integer | 可选 | 403 | [200, ...] | 当请求 URI 命中`block_rules`中的任何一个时,将返回的 HTTP 状态代码. |
| rejected_code | integer | 可选 | 403 | [200, ...] | 当请求 URI 命中`block_rules`中的任何一个时,将返回的 HTTP 状态代码。 |
| rejected_msg | string | 可选 | | 非空 | 当请求 URI 命中`block_rules`中的任何一个时,将返回的 HTTP 响应体。 |
## 启用方式
@ -76,6 +77,20 @@ Server: APISIX web server
... ...
```
如果你设置了属性 `rejected_msg` 的值为 `"access is not allowed"` ,将会收到如下的响应体:
```shell
$ curl -i http://127.0.0.1:9080/root.exe?a=a
HTTP/1.1 403 Forbidden
Date: Wed, 17 Jun 2020 13:55:41 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 150
Connection: keep-alive
Server: APISIX web server
{"error_msg":"access is not allowed"}
```
## 禁用插件
当想禁用`uri blocker`插件时,非常简单,只需要在插件配置中删除相应的 json 配置,无需重启服务,即可立即生效:

104
t/plugin/uri-blocker.t vendored
View File

@ -332,3 +332,107 @@ GET /hello?name=;union%20select%20
GET /hello?cc=2
--- no_error_log
[error]
=== TEST 16: invalid rejected_msg length or type
--- config
location /t {
content_by_lua_block {
local data = {
{
input = {
plugins = {
["uri-blocker"] = {
block_rules = { "^a" },
rejected_msg = "",
},
},
uri = "/hello",
},
output = {
error_msg = "failed to check the configuration of plugin uri-blocker err: property \"rejected_msg\" validation failed: string too short, expected at least 1, got 0",
},
},
{
input = {
plugins = {
["uri-blocker"] = {
block_rules = { "^a" },
rejected_msg = true,
},
},
uri = "/hello",
},
output = {
error_msg = "failed to check the configuration of plugin uri-blocker err: property \"rejected_msg\" validation failed: wrong type: expected string, got boolean",
},
},
}
local t = require("lib.test_admin").test
local err_count = 0
for i in ipairs(data) do
local code, body = t('/apisix/admin/routes/1', ngx.HTTP_PUT, data[i].input, data[i].output)
if code >= 300 then
err_count = err_count + 1
end
ngx.print(body)
end
assert(err_count == #data)
}
}
--- request
GET /t
--- no_error_log
[error]
=== TEST 17: one block rule, with rejected_msg
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {
"uri-blocker": {
"block_rules": ["aa"],
"rejected_msg": "access is not allowed"
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.print(body)
}
}
--- request
GET /t
--- no_error_log
[error]
=== TEST 18: hit block rule and return rejected_msg
--- request
GET /hello?aa=1
--- error_code: 403
--- response_body
{"error_msg":"access is not allowed"}
--- no_error_log
[error]