This is an automated email from the ASF dual-hosted git repository.
shreemaanabhishek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new a7a5a2be5 feat: support more sensitive fields for encryption (#11095)
a7a5a2be5 is described below
commit a7a5a2be54bc252f0ff2492928c2643710cbefad
Author: Abhishek Choudhary <[email protected]>
AuthorDate: Fri Mar 29 09:57:34 2024 +0545
feat: support more sensitive fields for encryption (#11095)
---
apisix/plugins/jwe-decrypt.lua | 30 +++++++++----
apisix/plugins/openid-connect.lua | 2 +-
apisix/plugins/openwhisk.lua | 3 +-
t/plugin/jwe-decrypt.t | 66 ++++++++++++++++++++--------
t/plugin/openid-connect.t | 91 ++++++++++++++++++++++++---------------
t/plugin/openwhisk.t | 52 +++++++++++++++-------
6 files changed, 163 insertions(+), 81 deletions(-)
diff --git a/apisix/plugins/jwe-decrypt.lua b/apisix/plugins/jwe-decrypt.lua
index 0e4447e02..b0d1e16f6 100644
--- a/apisix/plugins/jwe-decrypt.lua
+++ b/apisix/plugins/jwe-decrypt.lua
@@ -51,6 +51,7 @@ local consumer_schema = {
is_base64_encoded = { type = "boolean" },
},
required = { "key", "secret" },
+ encrypt_fields = { "key", "secret" },
}
@@ -71,15 +72,26 @@ function _M.check_schema(conf, schema_type)
return false, err
end
- -- restrict the length of secret, we use A256GCM for encryption,
- -- so the length should be 32 chars only
- if conf.is_base64_encoded then
- if #base64.decode_base64url(conf.secret) ~= 32 then
- return false, "the secret length after base64 decode should
be 32 chars"
- end
- else
- if #conf.secret ~= 32 then
- return false, "the secret length should be 32 chars"
+ local local_conf, err = core.config.local_conf(true)
+ if not local_conf then
+ return false, "failed to load the configuration file: " .. err
+ end
+
+ local encrypted = core.table.try_read_attr(local_conf, "apisix",
"data_encryption",
+ "enable_encrypt_fields") and (core.config.type == "etcd")
+
+ -- if encrypted, the secret length will exceed 32 so don't check
+ if not encrypted then
+ -- restrict the length of secret, we use A256GCM for encryption,
+ -- so the length should be 32 chars only
+ if conf.is_base64_encoded then
+ if #base64.decode_base64url(conf.secret) ~= 32 then
+ return false, "the secret length after base64 decode
should be 32 chars"
+ end
+ else
+ if #conf.secret ~= 32 then
+ return false, "the secret length should be 32 chars"
+ end
end
end
diff --git a/apisix/plugins/openid-connect.lua
b/apisix/plugins/openid-connect.lua
index 435cf6363..da334ebfb 100644
--- a/apisix/plugins/openid-connect.lua
+++ b/apisix/plugins/openid-connect.lua
@@ -268,7 +268,7 @@ local schema = {
}
}
},
- encrypt_fields = {"client_secret"},
+ encrypt_fields = {"client_secret", "client_rsa_private_key"},
required = {"client_id", "client_secret", "discovery"}
}
diff --git a/apisix/plugins/openwhisk.lua b/apisix/plugins/openwhisk.lua
index 7043f14f5..718513adc 100644
--- a/apisix/plugins/openwhisk.lua
+++ b/apisix/plugins/openwhisk.lua
@@ -49,7 +49,8 @@ local schema = {
keepalive_timeout = {type = "integer", minimum = 1000, default =
60000},
keepalive_pool = {type = "integer", minimum = 1, default = 5}
},
- required = {"api_host", "service_token", "namespace", "action"}
+ required = {"api_host", "service_token", "namespace", "action"},
+ encrypt_fields = {"service_token"}
}
diff --git a/t/plugin/jwe-decrypt.t b/t/plugin/jwe-decrypt.t
index e7fcf7756..af2af3291 100644
--- a/t/plugin/jwe-decrypt.t
+++ b/t/plugin/jwe-decrypt.t
@@ -95,6 +95,10 @@ done
=== TEST 4: secret length too long
+--- yaml_config
+apisix:
+ data_encryption:
+ enable_encrypt_fields: false
--- config
location /t {
content_by_lua_block {
@@ -115,6 +119,10 @@ done
=== TEST 5: secret length too long(base64 encode)
+--- yaml_config
+apisix:
+ data_encryption:
+ enable_encrypt_fields: false
--- config
location /t {
content_by_lua_block {
@@ -163,7 +171,27 @@ passed
-=== TEST 7: enable jwe-decrypt plugin using admin api
+=== TEST 7: verify encrypted field
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local t = require("lib.test_admin").test
+
+ -- get plugin conf from etcd, secret and key is encrypted
+ local etcd = require("apisix.core.etcd")
+ local res = assert(etcd.get('/consumers/jack'))
+ ngx.say(res.body.node.value.plugins["jwe-decrypt"].key)
+ ngx.say(res.body.node.value.plugins["jwe-decrypt"].secret)
+ }
+ }
+--- response_body
+XU29sA3FEVF68hGcdPo7sg==
+f9pGB0Dt4gYNCLKiINPfVSviKjQs2zfkBCT4+XZ3mDABZkJTr0orzYRD5CptDKMc
+
+
+
+=== TEST 8: enable jwe-decrypt plugin using admin api
--- config
location /t {
content_by_lua_block {
@@ -198,7 +226,7 @@ passed
-=== TEST 8: create public API route (jwe-decrypt sign)
+=== TEST 9: create public API route (jwe-decrypt sign)
--- config
location /t {
content_by_lua_block {
@@ -224,7 +252,7 @@ passed
-=== TEST 9: sign / verify in argument
+=== TEST 10: sign / verify in argument
--- config
location /t {
content_by_lua_block {
@@ -254,14 +282,14 @@ hello world
-=== TEST 10: test for unsupported method
+=== TEST 11: test for unsupported method
--- request
PATCH /apisix/plugin/jwe/encrypt?key=user-key
--- error_code: 404
-=== TEST 11: verify, missing token
+=== TEST 12: verify, missing token
--- request
GET /hello
--- error_code: 403
@@ -270,7 +298,7 @@ GET /hello
-=== TEST 12: verify: invalid JWE token
+=== TEST 13: verify: invalid JWE token
--- request
GET /hello
--- more_headers
@@ -281,7 +309,7 @@ Authorization:
invalid-eyJhbGciOiJkaXIiLCJraWQiOiJ1c2VyLWtleSIsImVuYyI6IkEyNTZHQ
-=== TEST 13: verify (in header)
+=== TEST 14: verify (in header)
--- request
GET /hello
--- more_headers
@@ -291,7 +319,7 @@ hello world
-=== TEST 14: verify (in header without Bearer)
+=== TEST 15: verify (in header without Bearer)
--- request
GET /hello
--- more_headers
@@ -301,7 +329,7 @@ hello world
-=== TEST 15: verify (header with bearer)
+=== TEST 16: verify (header with bearer)
--- request
GET /hello
--- more_headers
@@ -311,7 +339,7 @@ hello world
-=== TEST 16: verify (invalid bearer token)
+=== TEST 17: verify (invalid bearer token)
--- request
GET /hello
--- more_headers
@@ -322,7 +350,7 @@ Authorization: bearer
invalid-eyJhbGciOiJkaXIiLCJraWQiOiJ1c2VyLWtleSIsImVuYyI6Ik
-=== TEST 17: delete a exist consumer
+=== TEST 18: delete a exist consumer
--- config
location /t {
content_by_lua_block {
@@ -372,7 +400,7 @@ code: true body: passed
-=== TEST 18: add consumer with username and plugins with base64 secret
+=== TEST 19: add consumer with username and plugins with base64 secret
--- config
location /t {
content_by_lua_block {
@@ -402,7 +430,7 @@ passed
-=== TEST 19: enable jwt decrypt plugin with base64 secret
+=== TEST 20: enable jwt decrypt plugin with base64 secret
--- config
location /t {
content_by_lua_block {
@@ -436,7 +464,7 @@ passed
-=== TEST 20: create public API route (jwe-decrypt sign)
+=== TEST 21: create public API route (jwe-decrypt sign)
--- config
location /t {
content_by_lua_block {
@@ -462,7 +490,7 @@ passed
-=== TEST 21: sign / verify in argument
+=== TEST 22: sign / verify in argument
--- config
location /t {
content_by_lua_block {
@@ -494,7 +522,7 @@ hello world
-=== TEST 22: verify (in header)
+=== TEST 23: verify (in header)
--- request
GET /hello
--- more_headers
@@ -504,7 +532,7 @@ hello world
-=== TEST 23: verify (in header without Bearer)
+=== TEST 24: verify (in header without Bearer)
--- request
GET /hello
--- more_headers
@@ -514,7 +542,7 @@ hello world
-=== TEST 24: enable jwt decrypt plugin with test upstream route
+=== TEST 25: enable jwt decrypt plugin with test upstream route
--- config
location /t {
content_by_lua_block {
@@ -548,7 +576,7 @@ passed
-=== TEST 25: verify in upstream header
+=== TEST 26: verify in upstream header
--- request
GET /headers
--- more_headers
diff --git a/t/plugin/openid-connect.t b/t/plugin/openid-connect.t
index 6a8834867..427e439ad 100644
--- a/t/plugin/openid-connect.t
+++ b/t/plugin/openid-connect.t
@@ -106,6 +106,7 @@ done
"openid-connect": {
"client_id":
"kbyuFDidLLm280LIwVFiazOqjO3ty8KH",
"client_secret":
"60Op4HFM0I8ajz0WdiStAbziZ-VFQttXuxixHHs2R7r7-CW8GR79l-mmLqMhc-Sa",
+ "client_rsa_private_key":
"89ae4c8edadf1cd1c9f034335f136f87ad84b625c8f1",
"discovery":
"http://127.0.0.1:1980/.well-known/openid-configuration",
"redirect_uri": "https://iresty.com",
"ssl_verify": false,
@@ -135,7 +136,27 @@ passed
-=== TEST 5: Access route w/o bearer token. Should redirect to authentication
endpoint of ID provider.
+=== TEST 5: verify encrypted field
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local t = require("lib.test_admin").test
+
+
+ -- get plugin conf from etcd, client_rsa_private_key is encrypted
+ local etcd = require("apisix.core.etcd")
+ local res = assert(etcd.get('/routes/1'))
+
ngx.say(res.body.node.value.plugins["openid-connect"].client_rsa_private_key)
+
+ }
+ }
+--- response_body
+qO8TJbXcxCUnkkaTs3PxWDk5a54lv7FmngKQaxuXV4cL+7Kp1R4D8NS4w88so4e+
+
+
+
+=== TEST 6: Access route w/o bearer token. Should redirect to authentication
endpoint of ID provider.
--- config
location /t {
content_by_lua_block {
@@ -161,7 +182,7 @@ true
-=== TEST 6: Modify route to match catch-all URI `/*` and point plugin to local
Keycloak instance.
+=== TEST 7: Modify route to match catch-all URI `/*` and point plugin to local
Keycloak instance.
--- config
location /t {
content_by_lua_block {
@@ -208,7 +229,7 @@ passed
-=== TEST 7: Access route w/o bearer token and go through the full OIDC Relying
Party authentication process.
+=== TEST 8: Access route w/o bearer token and go through the full OIDC Relying
Party authentication process.
--- config
location /t {
content_by_lua_block {
@@ -266,7 +287,7 @@ x-userinfo: ey.*
-=== TEST 8: Re-configure plugin with respect to headers that get sent to
upstream.
+=== TEST 9: Re-configure plugin with respect to headers that get sent to
upstream.
--- config
location /t {
content_by_lua_block {
@@ -312,7 +333,7 @@ passed
-=== TEST 9: Access route w/o bearer token and go through the full OIDC Relying
Party authentication process.
+=== TEST 10: Access route w/o bearer token and go through the full OIDC
Relying Party authentication process.
--- config
location /t {
content_by_lua_block {
@@ -367,7 +388,7 @@ x-real-ip: 127.0.0.1
-=== TEST 10: Update plugin with `bearer_only=true`.
+=== TEST 11: Update plugin with `bearer_only=true`.
--- config
location /t {
content_by_lua_block {
@@ -408,7 +429,7 @@ passed
-=== TEST 11: Access route w/o bearer token. Should return 401 (Unauthorized).
+=== TEST 12: Access route w/o bearer token. Should return 401 (Unauthorized).
--- timeout: 10s
--- request
GET /hello
@@ -420,7 +441,7 @@ OIDC introspection failed: No bearer token found in request.
-=== TEST 12: Access route with invalid Authorization header value. Should
return 400 (Bad Request).
+=== TEST 13: Access route with invalid Authorization header value. Should
return 400 (Bad Request).
--- timeout: 10s
--- request
GET /hello
@@ -432,7 +453,7 @@ OIDC introspection failed: Invalid Authorization header
format.
-=== TEST 13: Update plugin with ID provider public key, so tokens can be
validated locally.
+=== TEST 14: Update plugin with ID provider public key, so tokens can be
validated locally.
--- config
location /t {
content_by_lua_block {
@@ -482,7 +503,7 @@ passed
-=== TEST 14: Access route with valid token.
+=== TEST 15: Access route with valid token.
--- config
location /t {
content_by_lua_block {
@@ -506,7 +527,7 @@ true
-=== TEST 15: Update route URI to '/uri' where upstream endpoint returns
request headers in response body.
+=== TEST 16: Update route URI to '/uri' where upstream endpoint returns
request headers in response body.
--- config
location /t {
content_by_lua_block {
@@ -556,7 +577,7 @@ passed
-=== TEST 16: Access route with valid token in `Authorization` header. Upstream
should additionally get the token in the `X-Access-Token` header.
+=== TEST 17: Access route with valid token in `Authorization` header. Upstream
should additionally get the token in the `X-Access-Token` header.
--- request
GET /uri HTTP/1.1
--- more_headers
@@ -572,7 +593,7 @@ x-userinfo: ey.*
-=== TEST 17: Update plugin to only use `Authorization` header.
+=== TEST 18: Update plugin to only use `Authorization` header.
--- config
location /t {
content_by_lua_block {
@@ -626,7 +647,7 @@ passed
-=== TEST 18: Access route with valid token in `Authorization` header. Upstream
should not get the additional `X-Access-Token` header.
+=== TEST 19: Access route with valid token in `Authorization` header. Upstream
should not get the additional `X-Access-Token` header.
--- request
GET /uri HTTP/1.1
--- more_headers
@@ -640,7 +661,7 @@ x-real-ip: 127.0.0.1
-=== TEST 19: Switch route URI back to `/hello`.
+=== TEST 20: Switch route URI back to `/hello`.
--- config
location /t {
content_by_lua_block {
@@ -690,7 +711,7 @@ passed
-=== TEST 20: Access route with invalid token. Should return 401.
+=== TEST 21: Access route with invalid token. Should return 401.
--- config
location /t {
content_by_lua_block {
@@ -719,7 +740,7 @@ jwt signature verification failed
-=== TEST 21: Update route with Keycloak introspection endpoint and public key
removed. Should now invoke introspection endpoint to validate tokens.
+=== TEST 22: Update route with Keycloak introspection endpoint and public key
removed. Should now invoke introspection endpoint to validate tokens.
--- config
location /t {
content_by_lua_block {
@@ -762,7 +783,7 @@ passed
-=== TEST 22: Obtain valid token and access route with it.
+=== TEST 23: Obtain valid token and access route with it.
--- config
location /t {
content_by_lua_block {
@@ -822,7 +843,7 @@ token validate successfully by introspection
-=== TEST 23: Access route with an invalid token.
+=== TEST 24: Access route with an invalid token.
--- config
location /t {
content_by_lua_block {
@@ -851,7 +872,7 @@ OIDC introspection failed: invalid token
-=== TEST 24: Check defaults.
+=== TEST 25: Check defaults.
--- config
location /t {
content_by_lua_block {
@@ -880,7 +901,7 @@ OIDC introspection failed: invalid token
-=== TEST 25: Update plugin with ID provider jwks endpoint for token
verification.
+=== TEST 26: Update plugin with ID provider jwks endpoint for token
verification.
--- config
location /t {
content_by_lua_block {
@@ -924,7 +945,7 @@ passed
-=== TEST 26: Obtain valid token and access route with it.
+=== TEST 27: Obtain valid token and access route with it.
--- config
location /t {
content_by_lua_block {
@@ -984,7 +1005,7 @@ token validate successfully by jwks
-=== TEST 27: Access route with an invalid token.
+=== TEST 28: Access route with an invalid token.
--- config
location /t {
content_by_lua_block {
@@ -1013,7 +1034,7 @@ OIDC introspection failed: invalid jwt: invalid jwt string
-=== TEST 28: Modify route to match catch-all URI `/*` and add
post_logout_redirect_uri option.
+=== TEST 29: Modify route to match catch-all URI `/*` and add
post_logout_redirect_uri option.
--- config
location /t {
content_by_lua_block {
@@ -1060,7 +1081,7 @@ passed
-=== TEST 29: Access route w/o bearer token and request logout to redirect to
post_logout_redirect_uri.
+=== TEST 30: Access route w/o bearer token and request logout to redirect to
post_logout_redirect_uri.
--- config
location /t {
content_by_lua_block {
@@ -1126,7 +1147,7 @@ http://127.0.0.1:.*/hello
-=== TEST 30: Switch route URI back to `/hello` and enable pkce.
+=== TEST 31: Switch route URI back to `/hello` and enable pkce.
--- config
location /t {
content_by_lua_block {
@@ -1167,7 +1188,7 @@ passed
-=== TEST 31: Access route w/o bearer token. Should redirect to authentication
endpoint of ID provider with code_challenge parameters.
+=== TEST 32: Access route w/o bearer token. Should redirect to authentication
endpoint of ID provider with code_challenge parameters.
--- config
location /t {
content_by_lua_block {
@@ -1195,7 +1216,7 @@ true
-=== TEST 32: set use_jwks and set_userinfo_header to validate "x-userinfo" in
request header
+=== TEST 33: set use_jwks and set_userinfo_header to validate "x-userinfo" in
request header
--- config
location /t {
content_by_lua_block {
@@ -1241,7 +1262,7 @@ passed
-=== TEST 33: Access route to validate "x-userinfo" in request header
+=== TEST 34: Access route to validate "x-userinfo" in request header
--- config
location /t {
content_by_lua_block {
@@ -1306,7 +1327,7 @@ x-userinfo: ey.*
-=== TEST 34: Set up new route with plugin matching URI `/*`
+=== TEST 35: Set up new route with plugin matching URI `/*`
--- config
location /t {
content_by_lua_block {
@@ -1344,7 +1365,7 @@ passed
-=== TEST 35: Check whether auth0 can redirect normally using
post_logout_redirect_uri configuration
+=== TEST 36: Check whether auth0 can redirect normally using
post_logout_redirect_uri configuration
--- config
location /t {
content_by_lua_block {
@@ -1367,7 +1388,7 @@ true
-=== TEST 36: Set up new route with plugin matching URI `/*`
+=== TEST 37: Set up new route with plugin matching URI `/*`
--- config
location /t {
content_by_lua_block {
@@ -1405,7 +1426,7 @@ passed
-=== TEST 37: Check whether google can redirect normally using
post_logout_redirect_uri configuration
+=== TEST 38: Check whether google can redirect normally using
post_logout_redirect_uri configuration
--- config
location /t {
content_by_lua_block {
@@ -1428,7 +1449,7 @@ true
-=== TEST 38: Update plugin config to use_jwk and bear_only false
+=== TEST 39: Update plugin config to use_jwk and bear_only false
--- config
location /t {
content_by_lua_block {
@@ -1472,7 +1493,7 @@ passed
-=== TEST 39: Test that jwt with bearer_only false still allows a valid
Authorization header
+=== TEST 40: Test that jwt with bearer_only false still allows a valid
Authorization header
--- config
location /t {
content_by_lua_block {
diff --git a/t/plugin/openwhisk.t b/t/plugin/openwhisk.t
index f906c9994..dfd4d8398 100644
--- a/t/plugin/openwhisk.t
+++ b/t/plugin/openwhisk.t
@@ -117,7 +117,27 @@ passed
-=== TEST 5: hit route (with GET request)
+=== TEST 5: verify encrypted field
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local t = require("lib.test_admin").test
+
+
+ -- get plugin conf from etcd, service_token is encrypted
+ local etcd = require("apisix.core.etcd")
+ local res = assert(etcd.get('/routes/1'))
+ ngx.say(res.body.node.value.plugins["openwhisk"].service_token)
+
+ }
+ }
+--- response_body
+pe14btxogtzJ4qPM/W2qj0AQeUK/O5oegLkKJLkkSEsKUIjP+bgyO+qsTXuLrY/h/esLKrRulD2TOtf+Zt/Us+hxZ/svsMwXZqZ9T9/2wWyi8SKALLfTUZDiV69mxCwD2zNBze1jslMlPtdA9JFIOQ==
+
+
+
+=== TEST 6: hit route (with GET request)
--- request
GET /hello
--- response_body chomp
@@ -125,7 +145,7 @@ GET /hello
-=== TEST 6: hit route (with POST method and non-json format request body)
+=== TEST 7: hit route (with POST method and non-json format request body)
--- request
POST /hello
test=test
@@ -137,7 +157,7 @@ qr/"error":"The request content was malformed/
-=== TEST 7: setup route with plugin
+=== TEST 8: setup route with plugin
--- config
location /t {
content_by_lua_block {
@@ -172,7 +192,7 @@ passed
-=== TEST 8: hit route (with POST and correct request body)
+=== TEST 9: hit route (with POST and correct request body)
--- request
POST /hello
{"name": "world"}
@@ -183,7 +203,7 @@ Content-Type: application/json
-=== TEST 9: reset route to non-existent action
+=== TEST 10: reset route to non-existent action
--- config
location /t {
content_by_lua_block {
@@ -218,7 +238,7 @@ passed
-=== TEST 10: hit route (with non-existent action)
+=== TEST 11: hit route (with non-existent action)
--- request
POST /hello
{"name": "world"}
@@ -230,7 +250,7 @@ qr/"error":"The requested resource does not exist."/
-=== TEST 11: reset route to wrong api_host
+=== TEST 12: reset route to wrong api_host
--- config
location /t {
content_by_lua_block {
@@ -265,7 +285,7 @@ passed
-=== TEST 12: hit route (with wrong api_host)
+=== TEST 13: hit route (with wrong api_host)
--- request
POST /hello
{"name": "world"}
@@ -277,7 +297,7 @@ failed to process openwhisk action, err:
-=== TEST 13: reset route to packaged action
+=== TEST 14: reset route to packaged action
--- config
location /t {
content_by_lua_block {
@@ -313,7 +333,7 @@ passed
-=== TEST 14: hit route (with packaged action)
+=== TEST 15: hit route (with packaged action)
--- request
GET /hello
--- response_body chomp
@@ -321,7 +341,7 @@ GET /hello
-=== TEST 15: reset route to status code action
+=== TEST 16: reset route to status code action
--- config
location /t {
content_by_lua_block {
@@ -356,14 +376,14 @@ passed
-=== TEST 16: hit route (with packaged action)
+=== TEST 17: hit route (with packaged action)
--- request
GET /hello
--- error_code: 407
-=== TEST 17: reset route to headers action
+=== TEST 18: reset route to headers action
--- config
location /t {
content_by_lua_block {
@@ -398,7 +418,7 @@ passed
-=== TEST 18: hit route (with headers action)
+=== TEST 19: hit route (with headers action)
--- request
GET /hello
--- response_headers
@@ -406,7 +426,7 @@ test: header
-=== TEST 19: reset route to body action
+=== TEST 20: reset route to body action
--- config
location /t {
content_by_lua_block {
@@ -441,7 +461,7 @@ passed
-=== TEST 20: hit route (with body action)
+=== TEST 21: hit route (with body action)
--- request
GET /hello
--- response_body