Make WordPress Core

Opened 4 weeks ago

Last modified 6 days ago

#65050 assigned defect (bug)

REST API: Comments controller returns 403 instead of 404 for invalid post ID in update_item()

Reported by: saratheonline's profile saratheonline Owned by: saratheonline's profile saratheonline
Milestone: 7.1 Priority: normal
Severity: normal Version: trunk
Component: REST API Keywords: has-patch changes-requested
Focuses: coding-standards Cc:

Description

In WP_REST_Comments_Controller, the update_item() method returns HTTP

403 (Forbidden) when an invalid post ID is provided, but the correct status
code is 404 (Not Found).

The same file returns 404 for the identical scenario in get_item()
(line 418), making this inconsistent within the same controller.

403 implies the client lacks permission. 404 is correct here because
the post does not exist — it is a missing resource, not an authorization
failure.

Affected code (class-wp-rest-comments-controller.php)


if ( empty( $post ) ) {
    return new WP_Error(
        'rest_comment_invalid_post_id',
        __( 'Invalid post ID.' ),
        array( 'status' => 403 )  // incorrect
    );
}

Proposed Fix

array( 'status' => 404 )

Change History (6)

This ticket was mentioned in PR #11529 on WordPress/wordpress-develop by @saratheonline.


4 weeks ago
#1

update_item() was returning HTTP 403 (Forbidden) when a non-existent

post ID was provided. The correct status is 404 (Not Found), as the
resource is missing — not access-restricted.

This also makes update_item() consistent with get_item() in the
same controller, which already returns 404 for the same scenario.

Trac ticket: https://core.trac.wordpress.org/ticket/65050

Fixes: #65050

## Use of AI Tools

#2 @gaurangsondagar
4 weeks ago

  • Focuses coding-standards added

Tested patch: https://github.com/WordPress/wordpress-develop/pull/11529

Environment:

  • WordPress: 7.1-alpha-62161-src
  • PHP: 8.3.30
  • Browser: Chrome
  • Database: MySQL 8.4.8
  • OS: Ubuntu

Steps I followed:

  • Confirmed that 'update_item()' in 'WP_REST_Comments_Controller' returns a 403 status when an invalid post ID is provided.
  • Verified that the same scenario in get_item() correctly returns a 404 status.
  • This creates inconsistency within the same controller.

Agree that 404 is the correct response here, as the post does not exist and this is not a permission issue.

Tested the proposed fix and it resolves the issue as expected without introducing any regressions.

#3 @SergeyBiryukov
4 weeks ago

  • Milestone changed from Awaiting Review to 7.1

#4 @westonruter
3 weeks ago

  • Keywords changes-requested added

#5 @r1k0
3 weeks ago

  • Keywords needs-testing removed

Patch Testing Report

Patch Tested: https://github.com/WordPress/wordpress-develop/pull/11529

Environment

  • WordPress: 7.1-alpha-62161-src
  • PHP: 8.3.30
  • Server: nginx/1.29.5
  • Database: mysqli (Server: 8.4.8 / Client: mysqlnd 8.3.30)
  • Browser: Chrome 147.0.0.0
  • OS: Windows 10/11
  • Theme: Twenty Twenty-Five 1.4
  • MU Plugins: None activated
  • Plugins:
    • Test Reports 1.2.1

Steps taken

  1. Ensure you have the Application password from "Users > Profile".
  2. In your terminal, run this command:
    curl -X POST http://localhost:8889/wp-json/wp/v2/comments/1 \
    -u "admin" \
    -H "Content-Type: application/json" \
    -d '{"post": 9999}'
    
  3. You'll be prompted to enter a password. Enter the password you got from Application Password.
  4. Perform steps 2 - 3 before and after applying the patch.
  5. ✅ Patch is solving the problem.

Expected result

  • A 404 status code response is returned when you try to update with a non-existent post ID.

Additional Notes

  • Patch fixes the issue, updating keyword (removing "needs-testing"). Add it back if needed.

Screenshots/Screencast with results

  • Before:

https://i.ibb.co/5W6Sygw9/status-code-403.png

  • After:

https://i.ibb.co/fdPmcTnR/status-code-404.png

Last edited 3 weeks ago by r1k0 (previous) (diff)

#6 @yusufmudagal
6 days ago

Tested PR https://github.com/WordPress/wordpress-develop/pull/11529

I created a post and comment locally, then called WP_REST_Comments_Controller::update_item() with that comment ID and post => 999999.

Before the patch, the response was rest_comment_invalid_post_id with status 403.
After the patch, the same error code returns status 404.

This matches the behavior in get_item() and looks correct to me. Patch tests well.

Note: See TracTickets for help on using tickets.