bhuvan-somisetty opened a new issue, #14024:
URL: https://github.com/apache/apisix/issues/14024
### Current Behavior
In `apisix/plugins/csrf.lua`, `check_csrf_token` validates the CSRF token
provided by the client in request headers and cookies:
```lua
local function check_csrf_token(conf, ctx, token)
local token_str = ngx_decode_base64(token)
if not token_str then
core.log.error("csrf token base64 decode error")
return false
end
local token_table, err = core.json.decode(token_str)
if err then
core.log.error("decode token error: ", err)
return false
end
local random = token_table["random"]
if not random then
core.log.error("no random in token")
return false
end
local expires = token_table["expires"]
if not expires then
core.log.error("no expires in token")
return false
end
local time_now = ngx_time()
if conf.expires > 0 and time_now - expires > conf.expires then
core.log.error("token has expired")
return false
end
local sign = gen_sign(random, expires, conf.key)
if token_table["sign"] ~= sign then
core.log.error("Invalid signatures")
return false
end
return true
end
```
When a client provides a base64-encoded token whose decoded value is a JSON
primitive (such as `123`, `true`, or `null`), `core.json.decode(token_str)`
succeeds without error (`err = nil`) and returns a non-table value (number,
boolean, or userdata).
Because `check_csrf_token` does not check whether `type(token_table) ==
"table"`, accessing `token_table["random"]` raises an unhandled Lua runtime
error:
- `attempt to index a number value` (for JSON number e.g. `123`, base64
`MTIz`)
- `attempt to index a boolean value` (for JSON boolean e.g. `true`, base64
`dHJ1ZQ==`)
- `attempt to index a userdata value` (for JSON null e.g. `null`, base64
`bnVsbA==`)
Furthermore, if `expires` is not numeric or `random` is not a scalar type
(e.g. `{"random": {}, "expires": "invalid"}`), `time_now - expires` or string
concatenation in `gen_sign` triggers arithmetic / concatenation runtime
exceptions.
These runtime crashes cause APISIX to return HTTP 500 Internal Server Error
instead of cleanly returning HTTP 401 Unauthorized (`{"error_msg":"Failed to
verify the csrf token signature"}`).
### Expected Behavior
`check_csrf_token` should validate that `type(token_table) == "table"` and
verify that the token fields (`random`, `expires`, `sign`) are valid scalar
types. If invalid, it should return `false` so the plugin responds with HTTP
401 instead of crashing with HTTP 500.
### Error Logs
```text
2026/10/11 04:00:00 [error] 12345#12345: *67890 [lua] csrf.lua:106:
check_csrf_token(): attempt to index local 'token_table' (a number value),
client: 127.0.0.1, server: localhost, request: "POST /hello HTTP/1.1"
```
### Steps to Reproduce
1. Configure a route with the `csrf` plugin enabled.
2. Send a POST request with `apisix-csrf-token` header and cookie containing
base64 encoded JSON number `MTIz` (`123`):
```bash
curl -i -X POST http://127.0.0.1:9080/hello \
-H "apisix-csrf-token: MTIz" \
-H "Cookie: apisix-csrf-token=MTIz"
```
3. Observe HTTP 500 Internal Server Error and Lua crash log `attempt to
index local 'token_table' (a number value)`.
### Environment
- APISIX version (run `apisix version`): master (3.19.0)
- Operating system (run `uname -a`): Linux 5.15.0-generic x86_64
- OpenResty / Nginx version (run `openresty -V` or `nginx -V`):
openresty/1.25.3.1
- etcd version, if relevant (run `curl
http://127.0.0.1:9090/v1/server_info`): 3.5.11
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]