Make WordPress Core

Changeset 55769


Ignore:
Timestamp:
05/16/2023 02:47:21 PM (19 months ago)
Author:
audrasjb
Message:

Media: Prevent CSRF setting attachment thumbnails.

Props martinkrcho, paulkevan, peterwilsoncc, xknown, peterwilsoncc.
Merges [55764] to branch 6.2.

Location:
branches/6.2
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/6.2/src/js/media/views/frame/video-details.js

    r43309 r55769  
    107107            wp.ajax.send( 'set-attachment-thumbnail', {
    108108                data : {
     109                    _ajax_nonce: wp.media.view.settings.nonce.setAttachmentThumbnail,
    109110                    urls: urls,
    110111                    thumbnail_id: attachment.get( 'id' )
  • branches/6.2/src/wp-admin/includes/ajax-actions.php

    r55474 r55769  
    27722772    }
    27732773
     2774    if ( false === check_ajax_referer( 'set-attachment-thumbnail', '_ajax_nonce', false ) ) {
     2775        wp_send_json_error();
     2776    }
     2777
    27742778    $post_ids = array();
    27752779    // For each URL, try to find its corresponding post ID.
  • branches/6.2/src/wp-includes/media.php

    r55318 r55769  
    45294529        'captions'          => ! apply_filters( 'disable_captions', '' ),
    45304530        'nonce'             => array(
    4531             'sendToEditor' => wp_create_nonce( 'media-send-to-editor' ),
     4531            'sendToEditor'           => wp_create_nonce( 'media-send-to-editor' ),
     4532            'setAttachmentThumbnail' => wp_create_nonce( 'set-attachment-thumbnail' ),
    45324533        ),
    45334534        'post'              => array(
  • branches/6.2/tests/phpunit/tests/ajax/wpAjaxSendAttachmentToEditor.php

    r54722 r55769  
    102102        $this->assertSame( $expected, $response['data'] );
    103103    }
     104
     105    public function test_wp_ajax_set_attachment_thumbnail_success() {
     106        // Become an administrator.
     107        $post    = $_POST;
     108        $user_id = self::factory()->user->create(
     109            array(
     110                'role'       => 'administrator',
     111                'user_login' => 'user_36578_administrator',
     112                'user_email' => 'user_36578_administrator@example.com',
     113            )
     114        );
     115        wp_set_current_user( $user_id );
     116        $_POST = array_merge( $_POST, $post );
     117
     118        // Upload the attachment itself.
     119        $filename = DIR_TESTDATA . '/uploads/small-audio.mp3';
     120        $contents = file_get_contents( $filename );
     121
     122        $upload     = wp_upload_bits( wp_basename( $filename ), null, $contents );
     123        $attachment = $this->_make_attachment( $upload );
     124
     125        // Upload the thumbnail.
     126        $filename = DIR_TESTDATA . '/images/waffles.jpg';
     127        $contents = file_get_contents( $filename );
     128
     129        $upload    = wp_upload_bits( wp_basename( $filename ), null, $contents );
     130        $thumbnail = $this->_make_attachment( $upload );
     131
     132        // Set up a default request.
     133        $_POST['_ajax_nonce']  = wp_create_nonce( 'set-attachment-thumbnail' );
     134        $_POST['thumbnail_id'] = $thumbnail;
     135        $_POST['urls']         = array( wp_get_attachment_url( $attachment ) );
     136
     137        // Make the request.
     138        try {
     139            $this->_handleAjax( 'set-attachment-thumbnail' );
     140        } catch ( WPAjaxDieContinueException $e ) {
     141            unset( $e );
     142        }
     143
     144        // Get the response.
     145        $response = json_decode( $this->_last_response, true );
     146
     147        // Ensure everything is correct.
     148        $this->assertTrue( $response['success'] );
     149    }
     150
     151    public function test_wp_ajax_set_attachment_thumbnail_missing_nonce() {
     152        // Become an administrator.
     153        $post    = $_POST;
     154        $user_id = self::factory()->user->create(
     155            array(
     156                'role'       => 'administrator',
     157                'user_login' => 'user_36578_administrator',
     158                'user_email' => 'user_36578_administrator@example.com',
     159            )
     160        );
     161        wp_set_current_user( $user_id );
     162        $_POST = array_merge( $_POST, $post );
     163
     164        // Upload the attachment itself.
     165        $filename = DIR_TESTDATA . '/uploads/small-audio.mp3';
     166        $contents = file_get_contents( $filename );
     167
     168        $upload     = wp_upload_bits( wp_basename( $filename ), null, $contents );
     169        $attachment = $this->_make_attachment( $upload );
     170
     171        // Upload the thumbnail.
     172        $filename = DIR_TESTDATA . '/images/waffles.jpg';
     173        $contents = file_get_contents( $filename );
     174
     175        $upload    = wp_upload_bits( wp_basename( $filename ), null, $contents );
     176        $thumbnail = $this->_make_attachment( $upload );
     177
     178        // Set up a default request.
     179        $_POST['thumbnail_id'] = $thumbnail;
     180        $_POST['urls']         = array( wp_get_attachment_url( $attachment ) );
     181
     182        // Make the request.
     183        try {
     184            $this->_handleAjax( 'set-attachment-thumbnail' );
     185        } catch ( WPAjaxDieContinueException $e ) {
     186            unset( $e );
     187        }
     188
     189        // Get the response.
     190        $response = json_decode( $this->_last_response, true );
     191
     192        // Check that success is false without sending nonce.
     193        $this->assertFalse( $response['success'] );
     194    }
    104195}
Note: See TracChangeset for help on using the changeset viewer.