diff --git src/wp-includes/class-wp-xmlrpc-server.php src/wp-includes/class-wp-xmlrpc-server.php index 531dd50..0059840 100644 --- src/wp-includes/class-wp-xmlrpc-server.php +++ src/wp-includes/class-wp-xmlrpc-server.php @@ -6232,58 +6232,33 @@ class wp_xmlrpc_server extends IXR_Server { return $this->pingback_error( 0, __( 'Is there no link to us?' ) ); // let's find which post is linked to - // FIXME: does url_to_postid() cover all these cases already? - // if so, then let's use it and drop the old code. - $urltest = parse_url($pagelinkedto); - if ( $post_ID = url_to_postid($pagelinkedto) ) { - // $way - } elseif ( isset( $urltest['path'] ) && preg_match('#p/[0-9]{1,}#', $urltest['path'], $match) ) { - // the path defines the post_ID (archives/p/XXXX) - $blah = explode('/', $match[0]); - $post_ID = (int) $blah[1]; - } elseif ( isset( $urltest['query'] ) && preg_match('#p=[0-9]{1,}#', $urltest['query'], $match) ) { - // the querystring defines the post_ID (?p=XXXX) - $blah = explode('=', $match[0]); - $post_ID = (int) $blah[1]; - } elseif ( isset($urltest['fragment']) ) { - // an #anchor is there, it's either... - if ( intval($urltest['fragment']) ) { - // ...an integer #XXXX (simplest case) - $post_ID = (int) $urltest['fragment']; - } elseif ( preg_match('/post-[0-9]+/',$urltest['fragment']) ) { - // ...a post id in the form 'post-###' - $post_ID = preg_replace('/[^0-9]+/', '', $urltest['fragment']); - } elseif ( is_string($urltest['fragment']) ) { - // ...or a string #title, a little more complicated - $title = preg_replace('/[^a-z0-9]/i', '.', $urltest['fragment']); - $sql = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_title RLIKE %s", $title ); - if (! ($post_ID = $wpdb->get_var($sql)) ) { - // returning unknown error '0' is better than die()ing - return $this->pingback_error( 0, '' ); - } - } - } else { - // TODO: Attempt to extract a post ID from the given URL + $post_ID = url_to_postid($pagelinkedto); + if ( ! $post_ID ) { return $this->pingback_error( 33, __('The specified target URL cannot be used as a target. It either doesn’t exist, or it is not a pingback-enabled resource.' ) ); } - $post_ID = (int) $post_ID; + $post_ID = (int) $post_ID; $post = get_post($post_ID); - if ( !$post ) // Post_ID not found + if ( ! $post ) // Post_ID not found return $this->pingback_error( 33, __( 'The specified target URL cannot be used as a target. It either doesn’t exist, or it is not a pingback-enabled resource.' ) ); if ( $post_ID == url_to_postid($pagelinkedfrom) ) return $this->pingback_error( 0, __( 'The source URL and the target URL cannot both point to the same resource.' ) ); // Check if pings are on - if ( !pings_open($post) ) + if ( ! pings_open( $post ) ) return $this->pingback_error( 33, __( 'The specified target URL cannot be used as a target. It either doesn’t exist, or it is not a pingback-enabled resource.' ) ); // Let's check that the remote site didn't already pingback this entry - if ( $wpdb->get_results( $wpdb->prepare("SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_author_url = %s", $post_ID, $pagelinkedfrom) ) ) + $dupe_args = array( + 'comment_post_ID' => $post_ID, + 'author_url' => $pagelinkedfrom + ); + $comments = get_comments( $dupe_args ); + if ( ! empty( $comments ) ) { return $this->pingback_error( 48, __( 'The pingback has already been registered.' ) ); - + } // very stupid, but gives time to the 'from' server to publish ! sleep(1); @@ -6296,20 +6271,26 @@ class wp_xmlrpc_server extends IXR_Server { $http_api_args = array( 'timeout' => 10, 'redirection' => 0, - 'limit_response_size' => 153600, // 150 KB + 'limit_response_size' => 1048576, // 1mb 'user-agent' => "$user_agent; verifying pingback from $remote_ip", 'headers' => array( 'X-Pingback-Forwarded-For' => $remote_ip, ), ); + // Make sure the resource is a valid one before retrieving it + $request = wp_safe_remote_head( $pagelinkedfrom, $http_api_args ); + $content_type = wp_remote_retrieve_header( $request, 'content-type' ); + if ( is_wp_error( $request ) ) { + return $this->pingback_error( 16, __( 'The source URL does not exist.' ) ); + } + // Protect Against Someone Trying to Make Us Download Media Files + if ( preg_match( '#(image|audio|video|model)/#is', $content_type ) ) { + return $this->pingback_error( 17, __( 'The source URL does not contain a link to the target URL, and so cannot be used as a source.' ) ); + } $request = wp_safe_remote_get( $pagelinkedfrom, $http_api_args ); $remote_source = $remote_source_original = wp_remote_retrieve_body( $request ); - if ( ! $remote_source ) { - return $this->pingback_error( 16, __( 'The source URL does not exist.' ) ); - } - /** * Filter the pingback remote source. * @@ -6320,55 +6301,36 @@ class wp_xmlrpc_server extends IXR_Server { */ $remote_source = apply_filters( 'pre_remote_source', $remote_source, $pagelinkedto ); - // Work around bug in strip_tags(): - $remote_source = str_replace( ']*>/", "\n\n", $remote_source ); - - preg_match( '|