Skip to content

Commit

Permalink
JWT claim check policy: uri was not escape correctly
Browse files Browse the repository at this point in the history
The uri was not escaped correctly so the mapping rule will not work
as expected.

For example: Mapping rule: /api/{id}/whatever is supposed to match
/api/ 123/whatever and perform the JWT token check but instead APIcast
bypass the JWT token check due to mapping rule mismatch.
  • Loading branch information
tkan145 committed Nov 19, 2023
1 parent ec973b7 commit 4ec4322
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ local Condition = require('apicast.conditions.condition')
local MappingRule = require('apicast.mapping_rule')
local Operation = require('apicast.conditions.operation')
local TemplateString = require('apicast.template_string')
local escape = require("resty.http.uri_escape")

local ipairs = ipairs

Expand Down Expand Up @@ -58,6 +59,10 @@ end
local function is_rule_denied_request(rule, context)

local uri = context:get_uri()
-- URI need to be escaped to be able to match values with special characters
-- (like spaces)
-- Example: if URI is `/foo /bar` it will be translated to `/foo%20/bar`
local escaped_uri = escape.escape_uri(uri)
local request_method = ngx.req.get_method()

local resource = rule.resource:render(context)
Expand All @@ -71,7 +76,7 @@ local function is_rule_denied_request(rule, context)
-- the name of the metric is irrelevant
metric_system_name = 'hits'
})
if mapping_rule:matches(request_method, uri) then
if mapping_rule:matches(request_method, escaped_uri) then
mapping_rule_match = true
break
end
Expand Down
81 changes: 81 additions & 0 deletions t/apicast-policy-jwt-claim-check.t
Original file line number Diff line number Diff line change
Expand Up @@ -564,3 +564,84 @@ the URI is not longer valid at all, and JWT is not expected to work correctly.
["yay, api backend\n","Request blocked due to JWT claim policy\n"]
--- no_error_log
[error]



=== TEST 8: JWT claim reject request with invalid token and URI contain special characters
--- backend
location /transactions/oauth_authrep.xml {
content_by_lua_block {
ngx.exit(200)
}
}

--- configuration
{
"oidc": [
{
"issuer": "https://example.com/auth/realms/apicast",
"config": { "id_token_signing_alg_values_supported": [ "RS256" ] },
"keys": { "somekid": { "pem": "-----BEGIN PUBLIC KEY-----\nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALClz96cDQ965ENYMfZzG+Acu25lpx2K\nNpAALBQ+catCA59us7+uLY5rjQR6SOgZpCz5PJiKNAdRPDJMXSmXqM0CAwEAAQ==\n-----END PUBLIC KEY-----", "alg": "RS256" } }
}
],
"services": [
{
"id": 42,
"backend_version": "oauth",
"backend_authentication_type": "service_token",
"backend_authentication_value": "token-value",
"proxy": {
"authentication_method": "oidc",
"oidc_issuer_endpoint": "https://example.com/auth/realms/apicast",
"api_backend": "http://test:$TEST_NGINX_SERVER_PORT/",
"proxy_rules": [
{ "pattern": "/groups/{groupID}$", "http_method": "GET", "metric_system_name": "hits", "delta": 1 }
],
"policy_chain": [
{
"name": "apicast.policy.jwt_claim_check",
"configuration": {
"rules" : [{
"operations": [
{"op": "==", "jwt_claim": "foo", "jwt_claim_type": "plain", "value": "1"}
],
"combine_op": "and",
"methods": ["GET"],
"resource": "/groups/{groupdID}$"
}]
}
},
{ "name": "apicast.policy.apicast" }
]
}
}
]
}
--- upstream
location /groups {
content_by_lua_block {
ngx.say('yay, api backend');
}
}
--- request eval
[
"GET /groups/%2020",
"GET /groups/%2020%0A30"
]
--- more_headers eval
::authorization_bearer_jwt('audience', {
realm_access => {
roles => [ 'director' ]
},
foo => "invalid",
}, 'somekid')
--- error_code eval
[403, 403]
--- response_body eval
[
"Request blocked due to JWT claim policy\x{0a}",
"Request blocked due to JWT claim policy\x{0a}"
]
--- no_error_log
[error]

0 comments on commit 4ec4322

Please sign in to comment.