Skip to content

Commit

Permalink
feat(serverless-functions): isolate sandbox cache (#10417)
Browse files Browse the repository at this point in the history
  • Loading branch information
samugi authored Mar 31, 2023
1 parent 9658e9e commit 887c8d2
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 1 deletion.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@

## Unreleased

### Breaking Changes

#### Plugins

- **Serverless Functions**: `kong.cache` now points to a cache instance that is dedicated to the
Serverless Functions plugins: it does not provide access to the global kong cache. Access to
certain fields in kong.configuration has also been restricted.

### Additions

#### Core
Expand Down
11 changes: 10 additions & 1 deletion kong/plugins/pre-function/_handler.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
local resty_mlcache = require "resty.mlcache"
local sandbox = require "kong.tools.sandbox"
local kong_meta = require "kong.meta"

Expand All @@ -8,7 +9,15 @@ local config_cache do

local no_op = function() end

local sandbox_opts = { env = { kong = kong, ngx = ngx } }
local shm_name = "kong_db_cache"
local cache_name = "serverless_" .. shm_name
local cache = resty_mlcache.new(cache_name, shm_name, { lru_size = 1e4 })
local sandbox_kong = setmetatable({
cache = cache,
configuration = kong.configuration.remove_sensitive()
}, { __index = kong })

local sandbox_opts = { env = { kong = sandbox_kong, ngx = ngx } }

-- compiles the array for a phase into a single function
local function compile_phase_array(phase_funcs)
Expand Down
130 changes: 130 additions & 0 deletions spec/03-plugins/33-serverless-functions/02-access_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,38 @@ local mock_fn_ten = [[
ngx.var.args = nil
]]

-- cache is accessible
local mock_fn_eleven = [[
local ok, err = kong.cache:get("foo", nil, function() return "val" end)
if err then
ngx.exit(500)
end
local v = kong.cache:get("foo")
ngx.status = 200
ngx.say(v)
ngx.exit(ngx.status)
]]

-- cache does not allow access to gateway information
local mock_fn_twelve = [[
ngx.status = 200
ngx.say(tostring(kong.cache.cluster_events))
ngx.exit(ngx.status)
]]

-- configuration is accessible
local mock_fn_thirteen = [[
ngx.status = 200
ngx.say(kong.configuration.plugins[1])
ngx.exit(ngx.status)
]]

-- configuration restricts access to properties
local mock_fn_fourteen = [[
ngx.status = 200
ngx.say(kong.configuration.pg_password)
ngx.exit(ngx.status)
]]


describe("Plugin: serverless-functions", function()
Expand Down Expand Up @@ -138,6 +170,26 @@ for _, plugin_name in ipairs({ "pre-function", "post-function" }) do
hosts = { "ten." .. plugin_name .. ".com" },
}

local route11 = bp.routes:insert {
service = { id = service.id },
hosts = { "eleven." .. plugin_name .. ".com" },
}

local route12 = bp.routes:insert {
service = { id = service.id },
hosts = { "twelve." .. plugin_name .. ".com" },
}

local route13 = bp.routes:insert {
service = { id = service.id },
hosts = { "thirteen." .. plugin_name .. ".com" },
}

local route14 = bp.routes:insert {
service = { id = service.id },
hosts = { "fourteen." .. plugin_name .. ".com" },
}

bp.plugins:insert {
name = plugin_name,
route = { id = route1.id },
Expand Down Expand Up @@ -192,6 +244,30 @@ for _, plugin_name in ipairs({ "pre-function", "post-function" }) do
config = get_conf { mock_fn_ten },
}

bp.plugins:insert {
name = plugin_name,
route = { id = route11.id },
config = get_conf { mock_fn_eleven },
}

bp.plugins:insert {
name = plugin_name,
route = { id = route12.id },
config = get_conf { mock_fn_twelve },
}

bp.plugins:insert {
name = plugin_name,
route = { id = route13.id },
config = get_conf { mock_fn_thirteen },
}

bp.plugins:insert {
name = plugin_name,
route = { id = route14.id },
config = get_conf { mock_fn_fourteen },
}

assert(helpers.start_kong({
nginx_conf = "spec/fixtures/custom_nginx.template",
}))
Expand Down Expand Up @@ -364,6 +440,60 @@ for _, plugin_name in ipairs({ "pre-function", "post-function" }) do
end)
end)

describe("sandbox access", function()
it("can access cache", function()
local res = assert(client:send {
method = "GET",
path = "/status/200",
headers = {
["Host"] = "eleven." .. plugin_name .. ".com",
},
})
local body = assert.res_status(200, res)
assert.is_not_nil(body)
assert.equal("val", body)
end)

it("cannot access gateway information through the cache", function()
local res = assert(client:send {
method = "GET",
path = "/status/200",
headers = {
["Host"] = "twelve." .. plugin_name .. ".com",
},
})
local body = assert.res_status(200, res)
assert.is_not_nil(body)
assert.equal("nil", body)
end)

it("can access kong.configuration fields", function()
local res = assert(client:send {
method = "GET",
path = "/status/200",
headers = {
["Host"] = "thirteen." .. plugin_name .. ".com",
},
})
local body = assert.res_status(200, res)
assert.is_not_nil(body)
assert.equal("bundled", body)
end)

it("redacts sensitive configuration fields", function()
local res = assert(client:send {
method = "GET",
path = "/status/200",
headers = {
["Host"] = "fourteen." .. plugin_name .. ".com",
},
})
local body = assert.res_status(200, res)
assert.is_not_nil(body)
assert.match("%*+", body)
end)
end)

describe("issues", function()
it("does not crash even when query is cleared, #9246", function()
local res = client:get("/status/200?a=b", {
Expand Down

1 comment on commit 887c8d2

@khcp-gha-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bazel Build

Docker image available kong/kong:887c8d2492a2cad643a501c3f03f0cc6a2df22be
Artifacts available https://github.com/Kong/kong/actions/runs/4574122073

Please sign in to comment.