Make WordPress Core

Changeset 48498


Ignore:
Timestamp:
07/16/2020 09:54:37 PM (4 years ago)
Author:
azaozz
Message:

REST API: Prevent attachment ID/image source mismatch when editing an image.

Fixes #50565.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php

    r48408 r48498  
    422422        $image_meta = wp_get_attachment_metadata( $attachment_id );
    423423
    424         if ( ! $image_meta || ! $image_file ) {
     424        if (
     425            ! $image_meta ||
     426            ! $image_file ||
     427            ! wp_image_file_matches_image_meta( $request['src'], $image_meta )
     428        ) {
    425429            return new WP_Error(
    426430                'rest_unknown_attachment',
     
    12901294                'maximum'     => 100,
    12911295            ),
     1296            'src'      => array(
     1297                'description' => __( 'URL to the edited image file.' ),
     1298                'type'        => 'string',
     1299                'format'      => 'uri',
     1300                'required'    => true,
     1301            ),
    12921302        );
    12931303    }
  • trunk/tests/phpunit/tests/rest-api/rest-attachments-controller.php

    r48464 r48498  
    17991799     */
    18001800    public function test_edit_image_returns_error_if_logged_out() {
    1801         $attachment = self::factory()->attachment->create();
     1801        $attachment = self::factory()->attachment->create_upload_object( $this->test_file );
    18021802
    18031803        $request  = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment}/edit" );
     1804        $request->set_body_params( array( 'src' => wp_get_attachment_image_url( $attachment, 'full' ) ) );
    18041805        $response = rest_do_request( $request );
    18051806        $this->assertErrorResponse( 'rest_cannot_edit_image', $response, 401 );
     
    18141815
    18151816        wp_set_current_user( $user->ID );
    1816         $attachment = self::factory()->attachment->create( array( 'post_author' => $user->ID ) );
     1817        $attachment = self::factory()->attachment->create_upload_object( $this->test_file );
    18171818
    18181819        $request  = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment}/edit" );
     1820        $request->set_body_params( array( 'src' => wp_get_attachment_image_url( $attachment, 'full' ) ) );
    18191821        $response = rest_do_request( $request );
    18201822        $this->assertErrorResponse( 'rest_cannot_edit_image', $response, 403 );
     
    18261828    public function test_edit_image_returns_error_if_cannot_edit() {
    18271829        wp_set_current_user( self::$uploader_id );
    1828         $attachment = self::factory()->attachment->create();
     1830        $attachment = self::factory()->attachment->create_upload_object( $this->test_file );
    18291831
    18301832        $request  = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment}/edit" );
     1833        $request->set_body_params( array( 'src' => wp_get_attachment_image_url( $attachment, 'full' ) ) );
    18311834        $response = rest_do_request( $request );
    18321835        $this->assertErrorResponse( 'rest_cannot_edit', $response, 403 );
     
    18411844
    18421845        $request  = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment}/edit" );
     1846        $request->set_body_params( array( 'src' => '/wp-content/uploads/2020/07/canola.jpg' ) );
    18431847        $response = rest_do_request( $request );
    18441848        $this->assertErrorResponse( 'rest_unknown_attachment', $response, 404 );
     
    18591863
    18601864        $request  = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment}/edit" );
     1865        $request->set_body_params( array( 'src' => wp_get_attachment_image_url( $attachment, 'full' ) ) );
    18611866        $response = rest_do_request( $request );
    18621867        $this->assertErrorResponse( 'rest_cannot_edit_file_type', $response, 400 );
     
    18711876
    18721877        $request  = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment}/edit" );
     1878        $request->set_body_params( array( 'src' => wp_get_attachment_image_url( $attachment, 'full' ) ) );
    18731879        $response = rest_do_request( $request );
    18741880        $this->assertErrorResponse( 'rest_image_not_edited', $response, 400 );
     
    18851891        WP_Image_Editor_Mock::$edit_return['rotate'] = new WP_Error();
    18861892
     1893        $params = array(
     1894            'rotation' => 60,
     1895            'src'      => wp_get_attachment_image_url( $attachment, 'full' ),
     1896        );
     1897
    18871898        $request = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment}/edit" );
    1888         $request->set_body_params( array( 'rotation' => 60 ) );
     1899        $request->set_body_params( $params );
    18891900        $response = rest_do_request( $request );
    18901901        $this->assertErrorResponse( 'rest_image_rotation_failed', $response, 500 );
     
    19161927                'width'  => 10,
    19171928                'height' => 5,
     1929                'src'    => wp_get_attachment_image_url( $attachment, 'full' ),
     1930
    19181931            )
    19191932        );
     
    19351948        $attachment = self::factory()->attachment->create_upload_object( $this->test_file );
    19361949
     1950        $params = array(
     1951            'rotation' => 60,
     1952            'src'      => wp_get_attachment_image_url( $attachment, 'full' ),
     1953        );
     1954
    19371955        $request = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment}/edit" );
    1938         $request->set_body_params( array( 'rotation' => 60 ) );
     1956        $request->set_body_params( $params );
    19391957        $response = rest_do_request( $request );
    19401958        $item     = $response->get_data();
     
    19471965        $this->assertEquals( $attachment, $item['media_details']['parent_image']['attachment_id'] );
    19481966        $this->assertContains( 'canola', $item['media_details']['parent_image']['file'] );
     1967    }
     1968
     1969    /**
     1970     * @ticket 50565
     1971     */
     1972    public function test_edit_image_returns_error_if_mismatched_src() {
     1973        wp_set_current_user( self::$superadmin_id );
     1974        $attachment_id_image1 = self::factory()->attachment->create_upload_object( $this->test_file );
     1975        $attachment_id_image2 = self::factory()->attachment->create_upload_object( $this->test_file2 );
     1976        $attachment_id_file   = self::factory()->attachment->create();
     1977
     1978        // URL to the first uploaded image.
     1979        $image_src = wp_get_attachment_image_url( $attachment_id_image1, 'large' );
     1980
     1981        // Test: attachment ID points to a different, non-image attachment.
     1982        $request_1  = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment_id_file}/edit" );
     1983        $request_1->set_body_params( array( 'src' => $image_src ) );
     1984
     1985        $response_1 = rest_do_request( $request_1 );
     1986        $this->assertErrorResponse( 'rest_unknown_attachment', $response_1, 404 );
     1987
     1988        // Test: attachment ID points to a different image attachment.
     1989        $request_2  = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment_id_image2}/edit" );
     1990        $request_2->set_body_params( array( 'src' => $image_src ) );
     1991
     1992        $response_2 = rest_do_request( $request_2 );
     1993        $this->assertErrorResponse( 'rest_unknown_attachment', $response_2, 404 );
     1994
     1995        // Test: attachment src points to a sub-size of the image.
     1996        $request_3  = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment_id_image1}/edit" );
     1997        $request_3->set_body_params( array( 'src' => wp_get_attachment_image_url( $attachment_id_image1, 'medium' ) ) );
     1998
     1999        $response_3 = rest_do_request( $request_3 );
     2000        // 'rest_image_not_edited' as the file wasn't edited.
     2001        $this->assertErrorResponse( 'rest_image_not_edited', $response_3, 400 );
    19492002    }
    19502003
  • trunk/tests/qunit/fixtures/wp-api-generated.js

    r48291 r48498  
    23782378                            "description": "As a percentage of the image, the height to crop the image to.",
    23792379                            "type": "number"
     2380                        },
     2381                        "src": {
     2382                            "required": true,
     2383                            "description": "URL to the edited image file.",
     2384                            "type": "string"
    23802385                        }
    23812386                    }
Note: See TracChangeset for help on using the changeset viewer.