Skip to content

Commit 9c1b71e

Browse files
author
Foo Bar
committed
fix(admin): strip SSL private keys array in GET single and list responses
Admin API GET /apisix/admin/ssls/{id} cleared the `key` field (single-cert private key) but left the `keys` array (multi-cert private keys) intact. The list response (GET /apisix/admin/ssls) did not sanitize either `key` or `keys` at all. - Strip `keys = nil` alongside `key = nil` in single-resource GET - Add list response sanitization loop stripping both `key` and `keys` from every item
1 parent 474894e commit 9c1b71e

2 files changed

Lines changed: 139 additions & 0 deletions

File tree

apisix/admin/resource.lua

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,17 @@ function _M:get(id, conf, sub_path)
176176
-- not return private key for security
177177
if res.body and res.body.node and res.body.node.value then
178178
res.body.node.value.key = nil
179+
res.body.node.value.keys = nil
180+
end
181+
182+
-- list response (range query)
183+
if res.body and res.body.list then
184+
for _, item in ipairs(res.body.list) do
185+
if item.value then
186+
item.value.key = nil
187+
item.value.keys = nil
188+
end
189+
end
179190
end
180191
end
181192

t/admin/ssl.t

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,3 +800,131 @@ GET /t
800800
--- error_code: 400
801801
--- response_body
802802
{"error_msg":"invalid configuration: property \"certs\" validation failed: failed to validate item 1: value should match only one schema, but matches none"}
803+
804+
805+
806+
=== TEST 24: GET single ssl strips keys array from multi-cert response
807+
--- config
808+
location /t {
809+
content_by_lua_block {
810+
local core = require("apisix.core")
811+
local t = require("lib.test_admin")
812+
813+
local ssl_cert = t.read_file("t/certs/apisix.crt")
814+
local ssl_key = t.read_file("t/certs/apisix.key")
815+
local ssl_ecc_cert = t.read_file("t/certs/apisix_ecc.crt")
816+
local ssl_ecc_key = t.read_file("t/certs/apisix_ecc.key")
817+
local data = {
818+
cert = ssl_cert,
819+
key = ssl_key,
820+
sni = "test.com",
821+
certs = {ssl_ecc_cert},
822+
keys = {ssl_ecc_key},
823+
}
824+
825+
local code, body = t.test('/apisix/admin/ssls/1',
826+
ngx.HTTP_PUT,
827+
core.json.encode(data)
828+
)
829+
if code ~= 200 and code ~= 201 then
830+
ngx.say("PUT failed: ", code, " ", body)
831+
return
832+
end
833+
834+
local code2, _, raw_body2 = t.test('/apisix/admin/ssls/1',
835+
ngx.HTTP_GET
836+
)
837+
if code2 ~= 200 then
838+
ngx.say("GET failed: ", code2)
839+
return
840+
end
841+
842+
local res_data = core.json.decode(raw_body2)
843+
local value = res_data and res_data.value
844+
if value == nil then
845+
ngx.say("no value in response, body: ", raw_body2)
846+
return
847+
end
848+
849+
if value.key ~= nil then
850+
ngx.say("FAIL: key field not stripped, type: ", type(value.key))
851+
return
852+
end
853+
854+
if value.keys ~= nil then
855+
local keys_count = type(value.keys) == "table" and #value.keys or "n/a"
856+
ngx.say("FAIL: keys field not stripped, type: ", type(value.keys),
857+
", count: ", keys_count)
858+
return
859+
end
860+
861+
ngx.say("passed")
862+
}
863+
}
864+
--- request
865+
GET /t
866+
--- response_body
867+
passed
868+
869+
870+
871+
=== TEST 25: GET list ssl strips key and keys from all items
872+
--- config
873+
location /t {
874+
content_by_lua_block {
875+
local core = require("apisix.core")
876+
local t = require("lib.test_admin")
877+
878+
-- TEST 24 already created ssls/1 with multicerts; rely on test ordering
879+
local code2, _, raw_body2 = t.test('/apisix/admin/ssls',
880+
ngx.HTTP_GET
881+
)
882+
if code2 ~= 200 then
883+
ngx.say("GET list failed: ", code2)
884+
return
885+
end
886+
887+
local res_data = core.json.decode(raw_body2)
888+
local list = res_data and res_data.list
889+
if list == nil or #list == 0 then
890+
ngx.say("FAIL: empty list")
891+
return
892+
end
893+
894+
for i, item in ipairs(list) do
895+
local value = item.value
896+
if value then
897+
if value.key ~= nil then
898+
ngx.say("FAIL: item ", i, " key field not stripped")
899+
return
900+
end
901+
if value.keys ~= nil then
902+
ngx.say("FAIL: item ", i, " keys field not stripped")
903+
return
904+
end
905+
end
906+
end
907+
908+
ngx.say("passed")
909+
}
910+
}
911+
--- request
912+
GET /t
913+
--- response_body
914+
passed
915+
916+
917+
918+
=== TEST 26: cleanup ssl created in TEST 24
919+
--- config
920+
location /t {
921+
content_by_lua_block {
922+
local t = require("lib.test_admin").test
923+
local code, message = t('/apisix/admin/ssls/1', ngx.HTTP_DELETE)
924+
ngx.say("[delete] code: ", code, " message: ", message)
925+
}
926+
}
927+
--- request
928+
GET /t
929+
--- response_body
930+
[delete] code: 200 message: passed

0 commit comments

Comments
 (0)