Description
HTTP API (POST /http/process/execute): a context given as a JSON string that is valid but does not decode to an array ("1", "true", "\"abc\"", "null") passes the validation, then json_decode() returns a scalar (or null) passed where an array is expected: TypeError, 500.
- Queued execution (
queue: true, default): Symfony 500 error page (ProcessExecuteMessage::__construct(): $context must be of type array).
- Synchronous execution (
queue: false): 500 with the TypeError message as response, which exposes the server paths: "CleverAge\\ProcessBundle\\Manager\\ProcessManager::execute(): Argument #3 ($context) must be of type array, int given, called in /var/www/.../src/Controller/ProcessExecuteController.php ...".
A JSON scalar not wrapped in a string ("context": 1) is correctly rejected (422).
Reproduction
- Create a user with an API token (UI, user edit, "Generate token").
curl -X POST https://<host>/http/process/execute -H 'Authorization: Bearer <token>' -H 'Content-Type: application/json' -d '{"code": "<process>", "context": "1"}'
- Same with
"queue": false.
Actual: 500 in both cases (see above).
Expected: 422 with a validation message (the context must be a JSON object or array), as for the other invalid inputs.
Tested on main (2d1d566) with the functional test application (HttpProcessExecuteTest, JSON body, contexts "1", "true", "\"abc\"", "null", queued and synchronous), cleverage/process-bundle 5.1, PHP 8.5.11, Symfony 8.1.
Cause
HttpProcessExecution::$context is validated by AtLeastOneOf([new Json(), new Type('array')]): the Json constraint accepts any valid JSON, scalars included.
ProcessExecuteController decodes it with json_decode($context, true) and passes the result to ProcessExecuteMessage / ProcessManager::execute(), both typed array.
Found while typing this code for PHPStan level 10 (#18, #134): the @var mixed[] $context added there only documents the existing assumption.
Proposed fix
- Validate that a string context decodes to an array (e.g. a
Callback / custom constraint on HttpProcessExecution::$context, or decode it in HttpProcessExecuteValueResolver and validate the decoded value), so that the request is rejected with a 422.
- Optionally, do not return the raw
TypeError message in the synchronous response (server paths); out of the scope of this issue if handled separately.
- Functional tests in
HttpProcessExecuteTest (scalar JSON contexts, queued and synchronous: 422, no message dispatched).
Requirements
Breaking changes
None: these requests currently fail with a 500, they would be rejected with a 422.
Description
HTTP API (
POST /http/process/execute): acontextgiven as a JSON string that is valid but does not decode to an array ("1","true","\"abc\"","null") passes the validation, thenjson_decode()returns a scalar (ornull) passed where an array is expected:TypeError, 500.queue: true, default): Symfony 500 error page (ProcessExecuteMessage::__construct():$contextmust be of type array).queue: false): 500 with theTypeErrormessage as response, which exposes the server paths:"CleverAge\\ProcessBundle\\Manager\\ProcessManager::execute(): Argument #3 ($context) must be of type array, int given, called in /var/www/.../src/Controller/ProcessExecuteController.php ...".A JSON scalar not wrapped in a string (
"context": 1) is correctly rejected (422).Reproduction
curl -X POST https://<host>/http/process/execute -H 'Authorization: Bearer <token>' -H 'Content-Type: application/json' -d '{"code": "<process>", "context": "1"}'"queue": false.Actual: 500 in both cases (see above).
Expected:
422with a validation message (the context must be a JSON object or array), as for the other invalid inputs.Tested on
main(2d1d566) with the functional test application (HttpProcessExecuteTest, JSON body, contexts"1","true","\"abc\"","null", queued and synchronous), cleverage/process-bundle 5.1, PHP 8.5.11, Symfony 8.1.Cause
HttpProcessExecution::$contextis validated byAtLeastOneOf([new Json(), new Type('array')]): theJsonconstraint accepts any valid JSON, scalars included.ProcessExecuteControllerdecodes it withjson_decode($context, true)and passes the result toProcessExecuteMessage/ProcessManager::execute(), both typedarray.Found while typing this code for PHPStan level 10 (#18, #134): the
@var mixed[] $contextadded there only documents the existing assumption.Proposed fix
Callback/ custom constraint onHttpProcessExecution::$context, or decode it inHttpProcessExecuteValueResolverand validate the decoded value), so that the request is rejected with a 422.TypeErrormessage in the synchronous response (server paths); out of the scope of this issue if handled separately.HttpProcessExecuteTest(scalar JSON contexts, queued and synchronous: 422, no message dispatched).Requirements
Breaking changes
None: these requests currently fail with a 500, they would be rejected with a 422.