Skip to content

Commit 83de016

Browse files
Grouped backports to the 4.5 branch.
- Media: Prevent CSRF setting attachment thumbnails. - Embeds: Add protocol validation for WordPress Embed code. Merges [55763] and [55764] to the 4.5 branch. Props dd32, isabel_brison, martinkrcho, matveb, ocean90, paulkevan, peterwilsoncc, timothyblynjacobs, xknown, youknowriad. git-svn-id: https://develop.svn.wordpress.org/branches/4.5@55780 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 95a7a60 commit 83de016

File tree

9 files changed

+127
-4
lines changed

9 files changed

+127
-4
lines changed

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "WordPress",
3-
"version": "4.5.28",
3+
"version": "4.5.29",
44
"description": "WordPress is web software you can use to create a beautiful website or blog.",
55
"repository": {
66
"type": "svn",

src/wp-admin/about.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,26 @@
4040

4141
<div class="changelog point-releases">
4242
<h3><?php _e( 'Maintenance and Security Releases' ); ?></h3>
43+
<p>
44+
<?php
45+
printf(
46+
/* translators: %s: WordPress version number */
47+
__( '<strong>Version %s</strong> addressed some security issues.' ),
48+
'4.5.29'
49+
);
50+
?>
51+
<?php
52+
printf(
53+
/* translators: %s: HelpHub URL */
54+
__( 'For more information, see <a href="%s">the release notes</a>.' ),
55+
sprintf(
56+
/* translators: %s: WordPress version */
57+
esc_url( __( 'https://wordpress.org/support/wordpress-version/version-%s/' ) ),
58+
sanitize_title( '4.5.29' )
59+
)
60+
);
61+
?>
62+
</p>
4363
<p>
4464
<?php
4565
printf(

src/wp-admin/includes/ajax-actions.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2168,6 +2168,10 @@ function wp_ajax_set_attachment_thumbnail() {
21682168
wp_send_json_error();
21692169
}
21702170

2171+
if ( false === check_ajax_referer( 'set-attachment-thumbnail', '_ajax_nonce', false ) ) {
2172+
wp_send_json_error();
2173+
}
2174+
21712175
$post_ids = array();
21722176
// For each URL, try to find its corresponding post ID.
21732177
foreach ( $_POST['urls'] as $url ) {

src/wp-includes/js/media/views/frame/video-details.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ VideoDetails = MediaDetails.extend({
104104

105105
wp.ajax.send( 'set-attachment-thumbnail', {
106106
data : {
107+
_ajax_nonce: wp.media.view.settings.nonce.setAttachmentThumbnail,
107108
urls: urls,
108109
thumbnail_id: attachment.get( 'id' )
109110
}

src/wp-includes/js/wp-embed.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
var iframes = document.querySelectorAll( 'iframe[data-secret="' + data.secret + '"]' ),
3939
blockquotes = document.querySelectorAll( 'blockquote[data-secret="' + data.secret + '"]' ),
40+
allowedProtocols = new RegExp( '^https?:$', 'i' ),
4041
i, source, height, sourceURL, targetURL;
4142

4243
for ( i = 0; i < blockquotes.length; i++ ) {
@@ -72,6 +73,11 @@
7273
sourceURL.href = source.getAttribute( 'src' );
7374
targetURL.href = data.value;
7475

76+
/* Only follow link if the protocol is in the allow list. */
77+
if ( ! allowedProtocols.test( targetURL.protocol ) ) {
78+
continue;
79+
}
80+
7581
/* Only continue if link hostname matches iframe's hostname. */
7682
if ( targetURL.host === sourceURL.host ) {
7783
if ( document.activeElement === source ) {

src/wp-includes/media.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3286,7 +3286,8 @@ function wp_enqueue_media( $args = array() ) {
32863286
/** This filter is documented in wp-admin/includes/media.php */
32873287
'captions' => ! apply_filters( 'disable_captions', '' ),
32883288
'nonce' => array(
3289-
'sendToEditor' => wp_create_nonce( 'media-send-to-editor' ),
3289+
'sendToEditor' => wp_create_nonce( 'media-send-to-editor' ),
3290+
'setAttachmentThumbnail' => wp_create_nonce( 'set-attachment-thumbnail' ),
32903291
),
32913292
'post' => array(
32923293
'id' => 0,

src/wp-includes/version.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* @global string $wp_version
66
*/
7-
$wp_version = '4.5.28-src';
7+
$wp_version = '4.5.29-src';
88

99
/**
1010
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.

tests/phpunit/tests/ajax/Attachments.php

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,95 @@ public function test_wp_ajax_send_attachment_to_editor_should_return_a_link() {
109109
$this->assertTrue( $response['success'] );
110110
$this->assertEquals( $expected, $response['data'] );
111111
}
112+
113+
public function test_wp_ajax_set_attachment_thumbnail_success() {
114+
// Become an administrator.
115+
$post = $_POST;
116+
$user_id = self::factory()->user->create(
117+
array(
118+
'role' => 'administrator',
119+
'user_login' => 'user_36578_administrator',
120+
'user_email' => '[email protected]',
121+
)
122+
);
123+
wp_set_current_user( $user_id );
124+
$_POST = array_merge( $_POST, $post );
125+
126+
// Upload the attachment itself.
127+
$filename = DIR_TESTDATA . '/uploads/small-audio.mp3';
128+
$contents = file_get_contents( $filename );
129+
130+
$upload = wp_upload_bits( wp_basename( $filename ), null, $contents );
131+
$attachment = $this->_make_attachment( $upload );
132+
133+
// Upload the thumbnail.
134+
$filename = DIR_TESTDATA . '/images/waffles.jpg';
135+
$contents = file_get_contents( $filename );
136+
137+
$upload = wp_upload_bits( wp_basename( $filename ), null, $contents );
138+
$thumbnail = $this->_make_attachment( $upload );
139+
140+
// Set up a default request.
141+
$_POST['_ajax_nonce'] = wp_create_nonce( 'set-attachment-thumbnail' );
142+
$_POST['thumbnail_id'] = $thumbnail;
143+
$_POST['urls'] = array( wp_get_attachment_url( $attachment ) );
144+
145+
// Make the request.
146+
try {
147+
$this->_handleAjax( 'set-attachment-thumbnail' );
148+
} catch ( WPAjaxDieContinueException $e ) {
149+
unset( $e );
150+
}
151+
152+
// Get the response.
153+
$response = json_decode( $this->_last_response, true );
154+
155+
// Ensure everything is correct.
156+
$this->assertTrue( $response['success'] );
157+
}
158+
159+
public function test_wp_ajax_set_attachment_thumbnail_missing_nonce() {
160+
// Become an administrator.
161+
$post = $_POST;
162+
$user_id = self::factory()->user->create(
163+
array(
164+
'role' => 'administrator',
165+
'user_login' => 'user_36578_administrator',
166+
'user_email' => '[email protected]',
167+
)
168+
);
169+
wp_set_current_user( $user_id );
170+
$_POST = array_merge( $_POST, $post );
171+
172+
// Upload the attachment itself.
173+
$filename = DIR_TESTDATA . '/uploads/small-audio.mp3';
174+
$contents = file_get_contents( $filename );
175+
176+
$upload = wp_upload_bits( wp_basename( $filename ), null, $contents );
177+
$attachment = $this->_make_attachment( $upload );
178+
179+
// Upload the thumbnail.
180+
$filename = DIR_TESTDATA . '/images/waffles.jpg';
181+
$contents = file_get_contents( $filename );
182+
183+
$upload = wp_upload_bits( wp_basename( $filename ), null, $contents );
184+
$thumbnail = $this->_make_attachment( $upload );
185+
186+
// Set up a default request.
187+
$_POST['thumbnail_id'] = $thumbnail;
188+
$_POST['urls'] = array( wp_get_attachment_url( $attachment ) );
189+
190+
// Make the request.
191+
try {
192+
$this->_handleAjax( 'set-attachment-thumbnail' );
193+
} catch ( WPAjaxDieContinueException $e ) {
194+
unset( $e );
195+
}
196+
197+
// Get the response.
198+
$response = json_decode( $this->_last_response, true );
199+
200+
// Check that success is false without sending nonce.
201+
$this->assertFalse( $response['success'] );
202+
}
112203
}

0 commit comments

Comments
 (0)