- Timestamp:
- 08/06/2026 09:30:58 AM (4 days ago)
- Location:
- trunk
- Files:
-
- 3 edited
-
src/wp-includes/comment.php (modified) (2 diffs)
-
tests/phpunit/tests/comment/checkComment.php (modified) (1 diff)
-
tests/phpunit/tests/comment/wpAllowComment.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/comment.php
r63012 r63036 21 21 * approved. 22 22 * 23 * Pingbacks originating from this site are automatically approved, as the link 24 * they report was created by someone who can already publish here. 25 * 23 26 * If all checks pass, the function will return true. 24 27 * 25 28 * @since 1.2.0 29 * @since 7.2.0 Pingbacks from this site are no longer held for moderation. 26 30 * 27 31 * @global wpdb $wpdb WordPress database abstraction object. … … 162 166 return false; 163 167 } 168 } elseif ( 'pingback' === $comment_type ) { 169 /* 170 * Only pingbacks are considered. A pingback is verified before it reaches 171 * this point: the source page is fetched, it must link to the target, and 172 * the comment is built from that fetched page. A trackback carries no such 173 * proof. Its source URL, title, and excerpt are unverified request data, so 174 * a forged trackback naming a local post as its source would be approved. 175 */ 176 177 // url_to_postid() compares hostnames, so it returns 0 for any URL that only appears to be local. 178 $source_id = url_to_postid( wp_unslash( $url ) ); 179 180 // Approve pingbacks reporting a link that someone who can already publish here created. 181 $approve_pingback = $source_id > 0 && 'publish' === get_post_status( $source_id ); 182 183 /** 184 * Filters whether a pingback is approved without being held for moderation. 185 * 186 * Defaults to true for pingbacks originating from a published post on this 187 * site, and false for every other pingback. Trackbacks are never considered, 188 * as they cannot be verified. 189 * 190 * @since 7.2.0 191 * 192 * @param bool $approve_pingback Whether to approve the pingback. 193 * @param int $source_id ID of the post on this site the pingback 194 * originated from, or 0 if it came from elsewhere. 195 * @param string $url The URL the pingback was sent from. 196 */ 197 return (bool) apply_filters( 'auto_approve_pingback', $approve_pingback, $source_id, $url ); 164 198 } else { 165 199 return false; -
trunk/tests/phpunit/tests/comment/checkComment.php
r56548 r63036 206 206 $this->assertFalse( $results ); 207 207 } 208 209 /** 210 * @ticket 65016 211 */ 212 public function test_should_return_true_for_a_pingback_from_this_site() { 213 update_option( 'comment_previously_approved', '1' ); 214 215 $source_url = get_permalink( self::factory()->post->create() ); 216 217 $this->assertTrue( check_comment( 'Site Title', '', $source_url, 'Excerpt.', '192.168.0.1', '', 'pingback' ) ); 218 } 219 220 /** 221 * Trackbacks are never approved automatically. 222 * 223 * A trackback's source URL, title, and excerpt are unverified request data. Were 224 * they trusted, anyone could POST a trackback naming a local post as its source 225 * and have arbitrary content approved without moderation. 226 * 227 * @ticket 65016 228 */ 229 public function test_should_return_false_for_a_trackback_claiming_a_local_source() { 230 update_option( 'comment_previously_approved', '1' ); 231 232 $source_url = get_permalink( self::factory()->post->create() ); 233 234 $this->assertFalse( check_comment( 'ForgedSite', '', $source_url, 'Spam.', '192.168.0.1', '', 'trackback' ) ); 235 } 236 237 /** 238 * @ticket 65016 239 * 240 * @dataProvider data_ping_types 241 * 242 * @param string $comment_type The comment type. 243 */ 244 public function test_should_return_false_for_a_ping_from_another_site( $comment_type ) { 245 update_option( 'comment_previously_approved', '1' ); 246 247 $this->assertFalse( check_comment( 'Site Title', '', 'http://example.com/a-post/', 'Excerpt.', '192.168.0.1', '', $comment_type ) ); 248 } 249 250 /** 251 * A URL is only local when its host matches, not when it merely contains the home URL. 252 * 253 * @ticket 65016 254 * 255 * @dataProvider data_ping_types 256 * 257 * @param string $comment_type The comment type. 258 */ 259 public function test_should_return_false_for_a_ping_from_a_url_spoofing_this_site( $comment_type ) { 260 update_option( 'comment_previously_approved', '1' ); 261 262 $post_id = self::factory()->post->create(); 263 $source_url = 'http://example.com/?ref=' . rawurlencode( get_permalink( $post_id ) ); 264 265 $this->assertFalse( check_comment( 'Site Title', '', $source_url, 'Excerpt.', '192.168.0.1', '', $comment_type ) ); 266 } 267 268 /** 269 * Manually approving every comment must not be bypassed by a self-pingback. 270 * 271 * @ticket 65016 272 */ 273 public function test_should_return_false_for_a_pingback_from_this_site_when_comment_moderation_is_enabled() { 274 update_option( 'comment_moderation', '1' ); 275 276 $source_url = get_permalink( self::factory()->post->create() ); 277 278 $this->assertFalse( check_comment( 'Site Title', '', $source_url, 'Excerpt.', '192.168.0.1', '', 'pingback' ) ); 279 } 280 281 /** 282 * The source post must be published, not a draft that happens to resolve. 283 * 284 * @ticket 65016 285 */ 286 public function test_should_return_false_for_a_pingback_from_an_unpublished_post_on_this_site() { 287 update_option( 'comment_previously_approved', '1' ); 288 289 $post_id = self::factory()->post->create( array( 'post_status' => 'draft' ) ); 290 $source_url = add_query_arg( 'p', $post_id, home_url( '/' ) ); 291 292 $this->assertFalse( check_comment( 'Site Title', '', $source_url, 'Excerpt.', '192.168.0.1', '', 'pingback' ) ); 293 } 294 295 /** 296 * Only pings are exempt. A regular comment linking to a local post is still moderated. 297 * 298 * @ticket 65016 299 */ 300 public function test_should_return_false_for_a_comment_whose_author_url_is_a_post_on_this_site() { 301 update_option( 'comment_previously_approved', '1' ); 302 303 $source_url = get_permalink( self::factory()->post->create() ); 304 305 $this->assertFalse( check_comment( 'Bob', 'bob@example.com', $source_url, 'A comment.', '192.168.0.1', '', 'comment' ) ); 306 } 307 308 /** 309 * @ticket 65016 310 */ 311 public function test_auto_approve_pingback_should_be_able_to_hold_a_pingback_from_this_site() { 312 update_option( 'comment_previously_approved', '1' ); 313 314 $source_url = get_permalink( self::factory()->post->create() ); 315 316 add_filter( 'auto_approve_pingback', '__return_false' ); 317 318 $this->assertFalse( check_comment( 'Site Title', '', $source_url, 'Excerpt.', '192.168.0.1', '', 'pingback' ) ); 319 } 320 321 /** 322 * @ticket 65016 323 */ 324 public function test_auto_approve_pingback_should_be_able_to_approve_a_pingback_from_another_site() { 325 update_option( 'comment_previously_approved', '1' ); 326 327 add_filter( 'auto_approve_pingback', '__return_true' ); 328 329 $this->assertTrue( check_comment( 'Site Title', '', 'http://example.com/a-post/', 'Excerpt.', '192.168.0.1', '', 'pingback' ) ); 330 } 331 332 /** 333 * @ticket 65016 334 */ 335 public function test_auto_approve_pingback_should_receive_the_source_post_id() { 336 update_option( 'comment_previously_approved', '1' ); 337 338 $post_id = self::factory()->post->create(); 339 $source_url = get_permalink( $post_id ); 340 341 $observed = null; 342 add_filter( 343 'auto_approve_pingback', 344 static function ( $approve, $source_id ) use ( &$observed ) { 345 $observed = $source_id; 346 return $approve; 347 }, 348 10, 349 2 350 ); 351 352 check_comment( 'Site Title', '', $source_url, 'Excerpt.', '192.168.0.1', '', 'pingback' ); 353 354 $this->assertSame( $post_id, $observed ); 355 } 356 357 /** 358 * Data provider. 359 * 360 * @return array[] 361 */ 362 public function data_ping_types() { 363 return array( 364 'pingback' => array( 'pingback' ), 365 'trackback' => array( 'trackback' ), 366 ); 367 } 208 368 } -
trunk/tests/phpunit/tests/comment/wpAllowComment.php
r53863 r63036 72 72 $result = wp_allow_comment( $comment_data ); 73 73 } 74 75 /** 76 * @ticket 65016 77 * 78 * @dataProvider data_should_approve_a_pingback_only_when_it_comes_from_this_site 79 * 80 * @param bool $is_self_ping Whether the pingback should come from this site. 81 * @param int $expected The expected approval status. 82 */ 83 public function test_should_approve_a_pingback_only_when_it_comes_from_this_site( $is_self_ping, $expected ) { 84 update_option( 'comment_previously_approved', '1' ); 85 86 $source_url = $is_self_ping 87 ? get_permalink( self::factory()->post->create() ) 88 : 'http://example.com/their-post/'; 89 90 $comment_data = array( 91 'comment_post_ID' => self::$post_id, 92 'comment_author' => 'The Linking Post', 93 'comment_author_email' => '', 94 'comment_author_url' => $source_url, 95 'comment_content' => '[…] an earlier post of mine […]', 96 'comment_author_IP' => '192.168.0.1', 97 'comment_parent' => 0, 98 'comment_date_gmt' => gmdate( 'Y-m-d H:i:s' ), 99 'comment_agent' => 'WordPress/6.8', 100 'comment_type' => 'pingback', 101 ); 102 103 $this->assertSame( $expected, wp_allow_comment( $comment_data ) ); 104 } 105 106 /** 107 * Data provider. 108 * 109 * @return array[] 110 */ 111 public function data_should_approve_a_pingback_only_when_it_comes_from_this_site() { 112 return array( 113 'a pingback from this site' => array( true, 1 ), 114 'a pingback from another site' => array( false, 0 ), 115 ); 116 } 74 117 }
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)