Problem/Motivation

The JSON:API spec states:

A server MUST return 409 Conflict when processing a POST request in which the resource object’s type is not among the type(s) that constitute the collection represented by the endpoint. Source

And:

A server MUST return 409 Conflict when processing a PATCH request in which the resource object’s type or id do not match the server’s endpoint. Source

However, JsonApiDocumentTopLevelNormalizer::validateRequestBody() checks that a request body includes a "type" member but does not check that the value matches the resource type of the requested endpoint. The type can be an arbitrary string. This is a spec violation.

Types are already checked for relationships.

Steps to reproduce

1. Enable JSON:API on a standard content entity, e.g. node.
2. POST to /jsonapi/node/article with a valid attributes payload but set data.type to an unrelated/invalid string, e.g. "type": "not-a-real-resource-type".
3. The request succeeds and the node is created, but it should fail because the type does not match.

Proposed resolution

validateRequestBody() now compares data.type to the resource type of the endpoint. A mismatch triggers a 409 Conflict response, per the JSON:API spec. The check runs for both POST and PATCH, since both operations call the same denormalize() method.

Test coverage

A kernel test exercises the denormalizer directly with a mismatched type. Functional tests send a mismatched type on POST and on PATCH and assert a 409 response with the expected error message.

Issue fork drupal-3612597

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

benstallings created an issue. See original summary.

benstallings’s picture

Assigned: benstallings » Unassigned
Status: Active » Needs review
ptmkenny’s picture

Status: Needs review » Needs work

Tests don't pass.

benstallings’s picture

Status: Needs work » Needs review
ptmkenny’s picture

Status: Needs review » Needs work
Issue tags: +Needs issue summary update, +Needs change record

The IS still has "Remaining tasks" that need to be resolved before commit.

It looks like the current issue summary is AI-generated and not updated for the MR; for example, one task is "Determine whether this should also apply to PATCH requests," but the current MR already applies to PATCH requests. Also the summary begins with "When creating or updating a resource via JSON:API (POST/PATCH), JsonApiDocumentTopLevelNormalizer::validateRequestBody() only checks that data.type is present in the request body" so it's not clear why determining whether to apply it to PATCH would be a "Remaining task."

Another item is "Add test coverage" but the MR already adds test coverage. So is there more test coverage to be added, or is the current test coverage sufficient?

If this change needs a change record, the change record needs to be included so that it can be evaluated along with the code.

The IS needs to be rewritten and verified by a human to accurately summarize the issue.

benstallings’s picture

Issue summary: View changes
benstallings’s picture

Thanks for the feedback @ptmkenny. I've updated the summary to reflect the current state. I haven't contributed a change record before, but I'll see what I can do!

benstallings’s picture

Status: Needs work » Needs review

change record added.

ptmkenny’s picture

Title: JsonApiDocumentTopLevelNormalizer::validateRequestBody() does not verify that the "type" member matches the requested resource type » JSON:API spec requires 409 conflict for type errors on POST and PATCH
Issue summary: View changes
Issue tags: -Needs issue summary update, -Needs change record

I rewrote the IS and change record. The real issue here is spec non-compliance.