Repository navigation
fix(graphql): reject non-object JSON request bodies - #14068
lordcheng10 wants to merge 3 commits into
Conversation
graphql-limit-count and graphql-proxy-cache decode the POST body and index it without checking its type. cjson decodes a scalar body such as 123 or true successfully, so the next res[query] indexes a number or boolean and raises an uncaught Lua error, answering 500 instead of the 400 used for other invalid GraphQL payloads. Reject any decoded body that is not a table and add regression tests for both plugins.
|
PTAL, thanks! @AlinsRan @Baoyuantop @nic-6443 @AlinsRan this touches the GraphQL request parsing you recently worked on; the change is a type guard around the decoded JSON body in both graphql-limit-count and graphql-proxy-cache. |
|
CI note: all 9 failing jobs stop in the dependency-install step before any test runs, with: This is caused by |
|
The only failing CI shard stopped during |
Description
Fix a crash in
graphql-limit-countandgraphql-proxy-cache: a POST bodythat is valid JSON but not a JSON object (for example
123ortrue) causedan 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:
cjsondecodes any JSON document, not only objects. A scalar body decodessuccessfully 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. Thebody 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 400shape as the existing "missing query field" path:
nullis covered as well:graphql-limit-countdecodes it tocjson.null(a non-table lightuserdata) andgraphql-proxy-cacheusesnull_as_nil, where it is already caught by the existingif not resbranch.Which issue(s) this PR fixes:
Fixes #14066
Checklist
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.tTEST 31 sends123as the JSON body andexpects 400 with
invalid graphql request, json body is not an object;t/plugin/graphql-proxy-cache/graphql.tTEST 22 does the same withtrue.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 number123with no error, and the followingres[GRAPHQL_REQ_QUERY]indexes it. With the added type check the requestreturns the 400 branch instead. CI will run both test files.