Skip to content

Commit 392ec50

Browse files
committed
Grouped backports to the 4.9 branch.
- Comments: Prevent users who can not see a post from seeing comments on it. - Shortcodes: Restrict media shortcode ajax to certain type. - REST API: Ensure no-cache headers are sent when methods are overridden. - REST API: Limit `search_columns` for users without `list_users`. - Prevent unintended behavior when certain objects are unserialized. Merges [56834], [56835], [56836], [56838], and [56840] to the 4.9 branch. Props xknown, jorbin, joehoyle, timothyblynjacobs, peterwilsoncc, ehtis, tykoted, antpb, rmccue. git-svn-id: https://develop.svn.wordpress.org/branches/4.9@56865 602fd350-edb4-49c9-b593-d223f7449a82
1 parent a392d87 commit 392ec50

File tree

13 files changed

+202
-24
lines changed

13 files changed

+202
-24
lines changed

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3140,13 +3140,29 @@ function wp_ajax_parse_media_shortcode() {
31403140

31413141
$shortcode = wp_unslash( $_POST['shortcode'] );
31423142

3143+
// Only process previews for media related shortcodes:
3144+
$found_shortcodes = get_shortcode_tags_in_content( $shortcode );
3145+
$media_shortcodes = array(
3146+
'audio',
3147+
'embed',
3148+
'playlist',
3149+
'video',
3150+
'gallery',
3151+
);
3152+
3153+
$other_shortcodes = array_diff( $found_shortcodes, $media_shortcodes );
3154+
3155+
if ( ! empty( $other_shortcodes ) ) {
3156+
wp_send_json_error();
3157+
}
3158+
31433159
if ( ! empty( $_POST['post_ID'] ) ) {
31443160
$post = get_post( (int) $_POST['post_ID'] );
31453161
}
31463162

31473163
// the embed shortcode requires a post
31483164
if ( ! $post || ! current_user_can( 'edit_post', $post->ID ) ) {
3149-
if ( 'embed' === $shortcode ) {
3165+
if ( in_array( 'embed', $found_shortcodes, true ) ) {
31503166
wp_send_json_error();
31513167
}
31523168
} else {

src/wp-admin/includes/class-wp-comments-list-table.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,19 @@ public function single_row( $item ) {
500500
}
501501
$this->user_can = current_user_can( 'edit_comment', $comment->comment_ID );
502502

503+
$edit_post_cap = $post ? 'edit_post' : 'edit_posts';
504+
if (
505+
current_user_can( $edit_post_cap, $comment->comment_post_ID ) ||
506+
(
507+
empty( $post->post_password ) &&
508+
current_user_can( 'read_post', $comment->comment_post_ID )
509+
)
510+
) {
511+
// The user has access to the post
512+
} else {
513+
return false;
514+
}
515+
503516
echo "<tr id='comment-$comment->comment_ID' class='$the_comment_class'>";
504517
$this->single_row_columns( $comment );
505518
echo "</tr>\n";

src/wp-admin/includes/class-wp-list-table.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,20 @@ protected function comments_bubble( $post_id, $pending_comments ) {
622622
$approved_phrase = sprintf( _n( '%s approved comment', '%s approved comments', $approved_comments ), $approved_comments_number );
623623
$pending_phrase = sprintf( _n( '%s pending comment', '%s pending comments', $pending_comments ), $pending_comments_number );
624624

625-
// No comments at all.
625+
$post_object = get_post( $post_id );
626+
$edit_post_cap = $post_object ? 'edit_post' : 'edit_posts';
627+
if (
628+
current_user_can( $edit_post_cap, $post_id ) ||
629+
(
630+
empty( $post_object->post_password ) &&
631+
current_user_can( 'read_post', $post_id )
632+
)
633+
) {
634+
// The user has access to the post and thus can see comments
635+
} else {
636+
return false;
637+
}
638+
626639
if ( ! $approved_comments && ! $pending_comments ) {
627640
printf( '<span aria-hidden="true">&#8212;</span><span class="screen-reader-text">%s</span>',
628641
__( 'No comments' )

src/wp-admin/includes/dashboard.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -919,8 +919,18 @@ function wp_dashboard_recent_comments( $total_items = 5 ) {
919919
echo '<h3>' . __( 'Recent Comments' ) . '</h3>';
920920

921921
echo '<ul id="the-comment-list" data-wp-lists="list:comment">';
922-
foreach ( $comments as $comment )
923-
_wp_dashboard_recent_comments_row( $comment );
922+
foreach ( $comments as $comment ) {
923+
$comment_post = get_post( $comment->comment_post_ID );
924+
if (
925+
current_user_can( 'edit_post', $comment->comment_post_ID ) ||
926+
(
927+
empty( $comment_post->post_password ) &&
928+
current_user_can( 'read_post', $comment->comment_post_ID )
929+
)
930+
) {
931+
_wp_dashboard_recent_comments_row( $comment );
932+
}
933+
}
924934
echo '</ul>';
925935

926936
if ( current_user_can( 'edit_posts' ) ) {

src/wp-includes/Requests/Hooks.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,8 @@ public function dispatch($hook, $parameters = array()) {
6565

6666
return true;
6767
}
68-
}
68+
69+
public function __wakeup() {
70+
throw new \LogicException( __CLASS__ . ' should never be unserialized' );
71+
}
72+
}

src/wp-includes/Requests/IRI.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,20 @@ public function is_valid() {
703703
return true;
704704
}
705705

706+
public function __wakeup() {
707+
$class_props = get_class_vars( __CLASS__ );
708+
$string_props = array( 'scheme', 'iuserinfo', 'ihost', 'port', 'ipath', 'iquery', 'ifragment' );
709+
$array_props = array( 'normalization' );
710+
foreach ( $class_props as $prop => $default_value ) {
711+
if ( in_array( $prop, $string_props, true ) && ! is_string( $this->$prop ) ) {
712+
throw new UnexpectedValueException();
713+
} elseif ( in_array( $prop, $array_props, true ) && ! is_array( $this->$prop ) ) {
714+
throw new UnexpectedValueException();
715+
}
716+
$this->$prop = null;
717+
}
718+
}
719+
706720
/**
707721
* Set the entire IRI. Returns true on success, false on failure (if there
708722
* are any invalid characters).

src/wp-includes/Requests/Session.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,10 @@ public function request_multiple($requests, $options = array()) {
227227
return Requests::request_multiple($requests, $options);
228228
}
229229

230+
public function __wakeup() {
231+
throw new \LogicException( __CLASS__ . ' should never be unserialized' );
232+
}
233+
230234
/**
231235
* Merge a request's data with the default data
232236
*

src/wp-includes/class-wp-theme.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,28 @@ public function parent() {
534534
return isset( $this->parent ) ? $this->parent : false;
535535
}
536536

537+
/**
538+
* Perform reinitialization tasks.
539+
*
540+
* Prevents a callback from being injected during unserialization of an object.
541+
*
542+
* @return void
543+
*/
544+
public function __wakeup() {
545+
if ( $this->parent && ! $this->parent instanceof self ) {
546+
throw new UnexpectedValueException();
547+
}
548+
if ( $this->headers && ! is_array( $this->headers ) ) {
549+
throw new UnexpectedValueException();
550+
}
551+
foreach ( $this->headers as $value ) {
552+
if ( ! is_string( $value ) ) {
553+
throw new UnexpectedValueException();
554+
}
555+
}
556+
$this->headers_sanitized = array();
557+
}
558+
537559
/**
538560
* Adds theme data to cache.
539561
*
@@ -1486,4 +1508,16 @@ private static function _name_sort_i18n( $a, $b ) {
14861508
// Don't mark up; Do translate.
14871509
return strnatcasecmp( $a->display( 'Name', false, true ), $b->display( 'Name', false, true ) );
14881510
}
1511+
1512+
private static function _check_headers_property_has_correct_type( $headers ) {
1513+
if ( ! is_array( $headers ) ) {
1514+
return false;
1515+
}
1516+
foreach ( $headers as $key => $value ) {
1517+
if ( ! is_string( $key ) || ! is_string( $value ) ) {
1518+
return false;
1519+
}
1520+
}
1521+
return true;
1522+
}
14891523
}

src/wp-includes/media.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,11 +1687,24 @@ function gallery_shortcode( $attr ) {
16871687
$attachments[$val->ID] = $_attachments[$key];
16881688
}
16891689
} elseif ( ! empty( $atts['exclude'] ) ) {
1690+
$post_parent_id = $id;
16901691
$attachments = get_children( array( 'post_parent' => $id, 'exclude' => $atts['exclude'], 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'] ) );
16911692
} else {
1693+
$post_parent_id = $id;
16921694
$attachments = get_children( array( 'post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'] ) );
16931695
}
16941696

1697+
if ( ! empty( $post_parent_id ) ) {
1698+
$post_parent = get_post( $post_parent_id );
1699+
1700+
// terminate the shortcode execution if user cannot read the post or password-protected
1701+
if (
1702+
( ! is_post_publicly_viewable( $post_parent->ID ) && ! current_user_can( 'read_post', $post_parent->ID ) )
1703+
|| post_password_required( $post_parent ) ) {
1704+
return '';
1705+
}
1706+
}
1707+
16951708
if ( empty( $attachments ) ) {
16961709
return '';
16971710
}
@@ -1991,6 +2004,15 @@ function wp_playlist_shortcode( $attr ) {
19912004
$attachments = get_children( $args );
19922005
}
19932006

2007+
if ( ! empty( $args['post_parent'] ) ) {
2008+
$post_parent = get_post( $id );
2009+
2010+
// terminate the shortcode execution if user cannot read the post or password-protected
2011+
if ( ! current_user_can( 'read_post', $post_parent->ID ) || post_password_required( $post_parent ) ) {
2012+
return '';
2013+
}
2014+
}
2015+
19942016
if ( empty( $attachments ) ) {
19952017
return '';
19962018
}

src/wp-includes/rest-api.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,7 @@ function rest_cookie_check_errors( $result ) {
783783
$result = wp_verify_nonce( $nonce, 'wp_rest' );
784784

785785
if ( ! $result ) {
786+
add_filter( 'rest_send_nocache_headers', '__return_true', 20 );
786787
return new WP_Error( 'rest_cookie_invalid_nonce', __( 'Cookie nonce is invalid' ), array( 'status' => 403 ) );
787788
}
788789

0 commit comments

Comments
 (0)