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

fix(vault): reference ending with slash when parsed should not return a key #13504

Merged
merged 2 commits into from
Aug 21, 2024
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
message: |
**Vault**: Reference ending with slash when parsed should not return a key.
type: bugfix
scope: PDK
38 changes: 22 additions & 16 deletions kong/pdk/vault.lua
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ local BRACE_START = byte("{")
local BRACE_END = byte("}")
local COLON = byte(":")
local SLASH = byte("/")
local BYT_V = byte("v")
local BYT_A = byte("a")
local BYT_U = byte("u")
local BYT_L = byte("l")
local BYT_T = byte("t")


local VAULT_QUERY_OPTS = { workspace = ngx.null }
Expand All @@ -72,13 +77,17 @@ local VAULT_QUERY_OPTS = { workspace = ngx.null }
-- @tparam string reference reference to check
-- @treturn boolean `true` is the passed in reference looks like a reference, otherwise `false`
local function is_reference(reference)
return type(reference) == "string"
and byte(reference, 1) == BRACE_START
and byte(reference, -1) == BRACE_END
and byte(reference, 7) == COLON
and byte(reference, 8) == SLASH
and byte(reference, 9) == SLASH
and sub(reference, 2, 6) == "vault"
return type(reference) == "string"
and byte(reference, 1) == BRACE_START
and byte(reference, 2) == BYT_V
and byte(reference, 3) == BYT_A
and byte(reference, 4) == BYT_U
and byte(reference, 5) == BYT_L
and byte(reference, 6) == BYT_T
and byte(reference, 7) == COLON
and byte(reference, 8) == SLASH
and byte(reference, 9) == SLASH
and byte(reference, -1) == BRACE_END
end


Expand Down Expand Up @@ -146,18 +155,15 @@ local function parse_reference(reference)
local key
local parts = parse_path(resource)
local count = #parts
if count == 1 then
if count == 0 then
return nil, fmt("reference url has invalid path [%s]", reference)
elseif count == 1 then
resource = unescape_uri(parts[1])

elseif parts.is_directory then
resource = unescape_uri(concat(parts, "/", 1, count))
else
resource = unescape_uri(concat(parts, "/", 1, count - 1))
if parts[count] ~= "" then
key = unescape_uri(parts[count])
end
end

if resource == "" then
return nil, fmt("reference url has invalid path [%s]", reference)
key = unescape_uri(parts[count])
end

local config
Expand Down
54 changes: 54 additions & 0 deletions spec/01-unit/23-vaults_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ describe("Vault PDK", function()
assert.is_nil(res.version)
end)

it("test init path with only slashes does not work", function()
local res, err = parse_reference("{vault://env}")
assert.is_nil(res)
assert.equal("reference url is missing path [{vault://env}]", err)

local res, err = parse_reference("{vault://env/}")
assert.is_nil(res)
assert.equal("reference url has empty path [{vault://env/}]", err)

local res, err = parse_reference("{vault://env/////}")
assert.is_nil(res)
assert.equal("reference url has invalid path [{vault://env/////}]", err)
end)

it("test init nested/path", function()
local res, err = parse_reference("{vault://env/test-secret/test-key}")
assert.is_nil(err)
Expand All @@ -80,6 +94,46 @@ describe("Vault PDK", function()
assert.is_nil(res.version)
end)

it("test init nested/path is url decoded", function()
local res, err = parse_reference("{vault://env/test%3Asecret/test%3Akey}")
assert.is_nil(err)
assert.is_nil(res.config)
assert.is_equal("env", res.name)
assert.is_equal("test:secret", res.resource)
assert.is_equal("test:key", res.key)
assert.is_nil(res.version)
end)

it("test init nested/path ignores consecutive slashes", function()
local res, err = parse_reference("{vault://env//////test-secret//////test-key}")
assert.is_nil(err)
assert.is_nil(res.config)
assert.is_equal("env", res.name)
assert.is_equal("test-secret", res.resource)
assert.is_equal("test-key", res.key)
assert.is_nil(res.version)
end)

it("test init nested/path ending with slash", function()
local res, err = parse_reference("{vault://env/test-secret/test-key/}")
assert.is_nil(err)
assert.is_nil(res.config)
assert.is_equal("env", res.name)
assert.is_equal("test-secret/test-key", res.resource)
assert.is_nil(res.key)
assert.is_nil(res.version)
end)

it("test init nested/path ending with slash ignores consecutive slashes", function()
local res, err = parse_reference("{vault://env//////test-secret//////test-key//////}")
assert.is_nil(err)
assert.is_nil(res.config)
assert.is_equal("env", res.name)
assert.is_equal("test-secret/test-key", res.resource)
assert.is_nil(res.key)
assert.is_nil(res.version)
end)

it("test init opts", function()
local res, err = parse_reference("{vault://env/test?opt1=val1}")
assert.is_nil(err)
Expand Down
Loading