Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(referer-restriction): add blacklist and message #4916

Merged
merged 3 commits into from
Aug 30, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions apisix/plugins/referer-restriction.lua
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,24 @@ local schema = {
whitelist = {
type = "array",
items = core.schema.host_def,
minItems = 1
minItems = 1,
},
blacklist = {
type = "array",
items = core.schema.host_def,
minItems = 1,
},
message = {
type = "string",
minLength = 1,
maxLength = 1024,
default = "Your referer host is not allowed",
},
},
oneOf = {
{required = {"whitelist"}},
{required = {"blacklist"}},
},
required = {"whitelist"},
}


Expand Down Expand Up @@ -110,12 +124,16 @@ function _M.access(conf, ctx)

elseif conf.whitelist then
local matcher = lrucache(conf.whitelist, nil,
create_host_matcher, conf.whitelist)
create_host_matcher, conf.whitelist)
block = not match_host(matcher, referer)
elseif conf.blacklist then
local matcher = lrucache(conf.blacklist, nil,
create_host_matcher, conf.blacklist)
block = match_host(matcher, referer)
end

if block then
return 403, { message = "Your referer host is not allowed" }
return 403, { message = conf.message }
end
end

Expand Down
9 changes: 7 additions & 2 deletions docs/en/latest/plugins/referer-restriction.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,20 @@ title: referer-restriction
## Name

The `referer-restriction` can restrict access to a Service or a Route by
whitelisting request header Referrers.
whitelisting/blacklisting request header Referrers.

## Attributes

| Name | Type | Requirement | Default | Valid | Description |
| --------- | ------------- | ----------- | ------- | ----- | ---------------------------------------- |
| whitelist | array[string] | required | | | List of hostname to whitelist. The hostname can be started with `*` as a wildcard |
| whitelist | array[string] | optional | | | List of hostname to whitelist. The hostname can be started with `*` as a wildcard |
| blacklist | array[string] | optional | | | List of hostname to blacklist. The hostname can be started with `*` as a wildcard |
| message | string | optional | Your referer host is not allowed | [1, 1024] | Message returned in case access is not allowed. |
| bypass_missing | boolean | optional | false | | Whether to bypass the check when the Referer header is missing or malformed |

One of `whitelist` or `blacklist` must be specified, and they can not work together.
The message can be user-defined.

## How To Enable

Creates a route or service object, and enable plugin `referer-restriction`.
Expand Down
9 changes: 7 additions & 2 deletions docs/zh/latest/plugins/referer-restriction.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,13 @@ title: referer-restriction

| 参数名 | 类型 | 可选项 | 默认值 | 有效值 | 描述 |
| --------- | ------------- | ------ | ------ | ------ | -------------------------------- |
| whitelist | array[string] | 必须 | | | 域名列表。域名开头可以用'*'作为通配符 |
| bypass_missing | boolean | 可选 | false | | 当 Referer 不存在或格式有误时,是否绕过检查 |
| whitelist | array[string] | 可选 | | | 白名单域名列表。域名开头可以用'*'作为通配符。 |
| blacklist | array[string] | 可选 | | | 黑名单域名列表。域名开头可以用'*'作为通配符。 |
| message | string | 可选 | Your referer host is not allowed | [1, 1024] | 在未允许访问的情况下返回的信息。 |
| bypass_missing | boolean | 可选 | false | | 当 Referer 不存在或格式有误时,是否绕过检查。 |

只能单独启用白名单或黑名单,两个不能一起使用。
`message`可以由用户自定义。

## 如何启用

Expand Down
83 changes: 83 additions & 0 deletions t/plugin/referer-restriction.t
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,86 @@ hello world
}
--- request
GET /t



=== TEST 10: set blacklist with reject message
--- 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,
[[{
"uri": "/hello",
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
},
"plugins": {
"referer-restriction": {
"blacklist": [
"*.xx.com"
],
"message": "Your referer host is deny"
}
}
}]]
)

if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed



=== TEST 11: hit route and in the blacklist
--- request
GET /hello
--- more_headers
Referer: http://www.xx.com
--- error_code: 403
--- response_body
{"message":"Your referer host is deny"}



=== TEST 12: hit route and not in the blacklist
--- request
GET /hello
--- more_headers
Referer: https://yy.com
--- response_body
hello world



=== TEST 13: whitelist and blacklist mutual exclusive
--- config
location /t {
content_by_lua_block {
local plugin = require("apisix.plugins.referer-restriction")
local ok, err = plugin.check_schema({whitelist={"xx.com"}, blacklist={"yy.com"}})
if not ok then
ngx.say(err)
end

ngx.say("done")
}
}
--- request
GET /t
--- response_body
value should match only one schema, but matches both schemas 1 and 2
done
--- no_error_log
okaybase marked this conversation as resolved.
Show resolved Hide resolved
[error]