lordcheng10 opened a new pull request, #14068:
URL: https://github.com/apache/apisix/pull/14068

   ### Description
   
   Fix a crash in `graphql-limit-count` and `graphql-proxy-cache`: a POST body
   that is valid JSON but not a JSON object (for example `123` or `true`) caused
   an uncaught Lua error and HTTP 500 instead of the 400 used for other invalid
   GraphQL payloads.
   
   Both plugins decode the request body and immediately index it:
   
   ```lua
   local res, err = core.json.decode(body)
   if not res then
       return false, "invalid graphql request, " .. err
   end
   
   if not res[GRAPHQL_REQ_QUERY] then
   ```
   
   `cjson` decodes any JSON document, not only objects. A scalar body decodes
   successfully to a Lua number, boolean or string, so `res[GRAPHQL_REQ_QUERY]`
   indexes a scalar and raises `attempt to index local 'res' (a number value)`
   inside `check_graphql_request.POST`, which runs during the access phase. The
   body is fully client controlled, so any request to a route with either plugin
   enabled can trigger it.
   
   Fix: reject a decoded body whose type is not `table`, returning the same 400
   shape as the existing "missing query field" path:
   
   ```
   invalid graphql request, json body is not an object
   ```
   
   `null` is covered as well: `graphql-limit-count` decodes it to
   `cjson.null` (a non-table lightuserdata) and `graphql-proxy-cache` uses
   `null_as_nil`, where it is already caught by the existing `if not res` 
branch.
   
   #### Which issue(s) this PR fixes:
   
   Fixes #14066
   
   ### Checklist
   
   - [x] I have explained the need for this PR and the problem it solves
   - [x] I have explained the changes or the new features added to this PR
   - [x] I have added tests corresponding to this change
   - [ ] I have updated the documentation to reflect this change
   - [x] I have verified that this change is backward compatible (If not, 
please discuss on the [APISIX mailing 
list](https://github.com/apache/apisix/tree/master#community) first)
   
   ### Additional notes
   
   No documentation update is needed: the configuration schema, the plugin
   behaviour for valid GraphQL requests and the error messages for the existing
   invalid-body cases are unchanged. Only bodies that previously crashed now 
get a
   deterministic 400.
   
   Regression tests:
   
   - `t/plugin/graphql-limit-count.t` TEST 31 sends `123` as the JSON body and
     expects 400 with `invalid graphql request, json body is not an object`;
   - `t/plugin/graphql-proxy-cache/graphql.t` TEST 22 does the same with `true`.
   
   Reviewer note on verification: this environment has no OpenResty, so the two
   test files could not be executed locally. The failure path is deterministic:
   `cjson.decode("123")` returns the number `123` with no error, and the 
following
   `res[GRAPHQL_REQ_QUERY]` indexes it. With the added type check the request
   returns the 400 branch instead. CI will run both test files.
   


-- 
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]

Reply via email to