Skip to content

Commit 6d320c0

Browse files
authored
fix(cas-auth): return 400 instead of 500 for SLO POST with empty body (#13471)
1 parent 0048226 commit 6d320c0

2 files changed

Lines changed: 82 additions & 1 deletion

File tree

apisix/plugins/cas-auth.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ function _M.access(conf, ctx)
381381

382382
if method == "POST" and uri == cas_callback_path then
383383
local data = core.request.get_body()
384-
local ticket = data:match("<samlp:SessionIndex>(.*)</samlp:SessionIndex>")
384+
local ticket = data and data:match("<samlp:SessionIndex>(.+)</samlp:SessionIndex>")
385385
if ticket == nil then
386386
return ngx.HTTP_BAD_REQUEST,
387387
{message = "invalid logout request from IdP, no ticket"}

t/plugin/cas-auth.t

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,3 +797,84 @@ passed
797797
}
798798
--- response_body
799799
passed
800+
801+
802+
803+
=== TEST 19: add route for empty-body SLO callback test
804+
--- config
805+
location /t {
806+
content_by_lua_block {
807+
local t = require("lib.test_admin").test
808+
809+
local code, body = t('/apisix/admin/routes/cas-slo',
810+
ngx.HTTP_PUT,
811+
[[{
812+
"methods": ["GET", "POST"],
813+
"host": "127.0.0.20",
814+
"priority": 10,
815+
"plugins": {
816+
"cas-auth": {
817+
"idp_uri": "http://127.0.0.1:8080/realms/test/protocol/cas",
818+
"cas_callback_uri": "/cas_callback",
819+
"logout_uri": "/logout",
820+
"cookie": {
821+
"secret": "0123456789abcdef0123456789abcdef",
822+
"secure": false
823+
}
824+
}
825+
},
826+
"upstream": {
827+
"nodes": {"127.0.0.1:1980": 1},
828+
"type": "roundrobin"
829+
},
830+
"uri": "/*"
831+
}]]
832+
)
833+
834+
if code >= 300 then
835+
ngx.status = code
836+
end
837+
ngx.say(body)
838+
}
839+
}
840+
--- response_body
841+
passed
842+
843+
844+
845+
=== TEST 20: malformed SLO POST to callback returns 400, not 500
846+
--- config
847+
location /t {
848+
content_by_lua_block {
849+
local http = require "resty.http"
850+
local httpc = http.new()
851+
local base = "http://127.0.0.1:" .. ngx.var.server_port
852+
853+
-- (1) no body at all: get_body() returns nil, which must not be
854+
-- indexed (500) but fall through to a clean 400.
855+
local res, err = httpc:request_uri(base .. "/cas_callback", {
856+
method = "POST",
857+
headers = { ["Host"] = "127.0.0.20" },
858+
})
859+
assert(res, "request failed: " .. tostring(err))
860+
assert(res.status == 400,
861+
"expected 400 for empty-body SLO POST, got " .. res.status)
862+
assert(res.body and res.body:find("no ticket", 1, true),
863+
"expected 'no ticket' message, got: " .. tostring(res.body))
864+
865+
-- (2) body present but SessionIndex empty: still a malformed
866+
-- logout, must be 400 rather than passing an empty ticket through.
867+
res, err = httpc:request_uri(base .. "/cas_callback", {
868+
method = "POST",
869+
headers = { ["Host"] = "127.0.0.20" },
870+
body = "<samlp:SessionIndex></samlp:SessionIndex>",
871+
})
872+
assert(res, "request failed: " .. tostring(err))
873+
assert(res.status == 400,
874+
"expected 400 for empty SessionIndex, got " .. res.status)
875+
876+
ngx.say("passed")
877+
}
878+
}
879+
--- response_body
880+
passed

0 commit comments

Comments
 (0)