Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
12 changes: 11 additions & 1 deletion apisix/plugins/basic-auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ local consumer_schema = {
title = "work with consumer object",
properties = {
username = { type = "string" },
password = { type = "string" },
password = {
type = "string",
minLength = 1,
},
},
encrypt_fields = {"password"},
required = {"username", "password"},
Expand Down Expand Up @@ -148,6 +151,13 @@ local function find_consumer(ctx)
return nil, nil, "Invalid user authorization"
end

-- RFC 8265 section 4.1: a password MUST NOT be zero-length. Fail closed
-- when the resolved password is empty, which also covers existing data
-- and $secret:// / $ENV:// references that resolve to "".
if password == "" or cur_consumer.auth_conf.password == "" then
return nil, nil, "Invalid user authorization"
end

if cur_consumer.auth_conf.password ~= password then
return nil, nil, "Invalid user authorization"
end
Expand Down
78 changes: 78 additions & 0 deletions t/plugin/basic-auth.t
Original file line number Diff line number Diff line change
Expand Up @@ -708,3 +708,81 @@ Authorization: bASiC Zm9vOmJhcg==
hello world
--- error_log
find consumer foo


=== TEST 40: consumer schema rejects empty password
--- config
location /t {
content_by_lua_block {
local core = require("apisix.core")
local plugin = require("apisix.plugins.basic-auth")
local ok, err = plugin.check_schema({username = 'foo', password = ''}, core.schema.TYPE_CONSUMER)
if ok then
ngx.say("unexpected: schema accepted empty password")
return
end
ngx.say(err or "rejected")
}
}
--- request
GET /t
--- response_body_like
property "password" validation failed
--- no_error_log
unexpected



=== TEST 41: admin api rejects consumer with empty password
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/consumers',
ngx.HTTP_PUT,
[[{
"username": "empty-pass",
"plugins": {
"basic-auth": {
"username": "empty-pass",
"password": ""
}
}
}]]
)
if code < 400 then
ngx.status = 500
ngx.say("unexpected: admin api accepted empty password")
return
end
ngx.status = code
ngx.say(body)
}
}
--- request
GET /t
--- error_code: 400
--- response_body_like
property "password" validation failed
--- no_error_log
unexpected



=== TEST 42: empty password in Authorization header is rejected
--- request
GET /hello
--- more_headers
Authorization: Basic Zm9vOg==
--- error_code: 401



=== TEST 43: whitespace-only password in Authorization header is rejected
--- request
GET /hello
--- more_headers
Authorization: Basic Zm9vOiA=
--- error_code: 401
--- response_body
{"message":"Invalid user authorization"}
Loading