diff --git a/apisix/plugins/referer-restriction.lua b/apisix/plugins/referer-restriction.lua index 867159911314..85e8ea3bc1e1 100644 --- a/apisix/plugins/referer-restriction.lua +++ b/apisix/plugins/referer-restriction.lua @@ -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"}, } @@ -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 diff --git a/docs/en/latest/plugins/referer-restriction.md b/docs/en/latest/plugins/referer-restriction.md index de54f1b51b5b..098fbf9ca232 100644 --- a/docs/en/latest/plugins/referer-restriction.md +++ b/docs/en/latest/plugins/referer-restriction.md @@ -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`. diff --git a/docs/zh/latest/plugins/referer-restriction.md b/docs/zh/latest/plugins/referer-restriction.md index 870ab68a89b3..562c50095152 100644 --- a/docs/zh/latest/plugins/referer-restriction.md +++ b/docs/zh/latest/plugins/referer-restriction.md @@ -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`可以由用户自定义。 ## 如何启用 diff --git a/t/plugin/referer-restriction.t b/t/plugin/referer-restriction.t index 3c765f563c7d..80914cf754c6 100644 --- a/t/plugin/referer-restriction.t +++ b/t/plugin/referer-restriction.t @@ -187,3 +187,84 @@ 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