Skip to content

Commit 4205e6e

Browse files
committed
Short-circuit validate_url() when attempting validation requests to other sites (which will always fail) (#6582)
1 parent 10afba2 commit 4205e6e

File tree

2 files changed

+65
-7
lines changed

2 files changed

+65
-7
lines changed

includes/validation/class-amp-validation-manager.php

+30-7
Original file line numberDiff line numberDiff line change
@@ -1752,6 +1752,24 @@ public static function validate_after_plugin_activation() {
17521752
return $validation_errors;
17531753
}
17541754

1755+
/**
1756+
* Validate a URL to be validated.
1757+
*
1758+
* @param string $url URL.
1759+
* @return string|WP_Error Validated URL or else error.
1760+
*/
1761+
private static function validate_validation_url( $url ) {
1762+
$validated_url = wp_validate_redirect( $url );
1763+
if ( ! $validated_url ) {
1764+
return new WP_Error(
1765+
'http_request_failed',
1766+
/* translators: %s is the URL being redirected to. */
1767+
sprintf( __( 'Unable to validate a URL on another site. Attempted to validate: %s', 'amp' ), $url )
1768+
);
1769+
}
1770+
return $validated_url;
1771+
}
1772+
17551773
/**
17561774
* Validates a given URL.
17571775
*
@@ -1778,7 +1796,13 @@ public static function validate_url( $url ) {
17781796
self::VALIDATE_QUERY_VAR => self::get_amp_validate_nonce(),
17791797
self::CACHE_BUST_QUERY_VAR => wp_rand(),
17801798
];
1781-
$validation_url = add_query_arg( $added_query_vars, $url );
1799+
1800+
// Ensure the URL to be validated is on the site.
1801+
$validation_url = self::validate_validation_url( $url );
1802+
if ( is_wp_error( $validation_url ) ) {
1803+
return $validation_url;
1804+
}
1805+
$validation_url = add_query_arg( $added_query_vars, $validation_url );
17821806

17831807
$r = null;
17841808

@@ -1818,13 +1842,12 @@ public static function validate_url( $url ) {
18181842
$location_header = preg_replace( '#(^https?://[^/]+)/.*#', '$1', home_url( '/' ) ) . $location_header;
18191843
}
18201844

1821-
// Block redirecting to a different host.
1822-
$location_header = wp_validate_redirect( $location_header );
1823-
if ( ! $location_header ) {
1824-
break;
1845+
// Prevent following a redirect to another site, which won't work for validation anyway.
1846+
$validation_url = self::validate_validation_url( $location_header );
1847+
if ( is_wp_error( $validation_url ) ) {
1848+
return $validation_url;
18251849
}
1826-
1827-
$validation_url = add_query_arg( $added_query_vars, $location_header );
1850+
$validation_url = add_query_arg( $added_query_vars, $validation_url );
18281851
}
18291852

18301853
if ( is_wp_error( $r ) ) {

tests/php/validation/test-class-amp-validation-manager.php

+35
Original file line numberDiff line numberDiff line change
@@ -2317,6 +2317,41 @@ public function test_validate_url( $validation_errors, $after_matter ) {
23172317
remove_filter( 'pre_http_request', $filter );
23182318
}
23192319

2320+
/**
2321+
* Test for validate_url() for a URL on another site.
2322+
*
2323+
* @covers AMP_Validation_Manager::validate_url()
2324+
*/
2325+
public function test_validate_url_on_another_site() {
2326+
$r = AMP_Validation_Manager::validate_url( 'https://another-site.example.com/' );
2327+
$this->assertInstanceOf( WP_Error::class, $r );
2328+
$this->assertEquals( 'http_request_failed', $r->get_error_code() );
2329+
$this->assertStringStartsWith( 'Unable to validate a URL on another site. Attempted to validate: https://another-site.example.com/', $r->get_error_message() );
2330+
}
2331+
2332+
/**
2333+
* Test for validate_url() for a URL that redirects to another site.
2334+
*
2335+
* @covers AMP_Validation_Manager::validate_url()
2336+
*/
2337+
public function test_validate_url_for_redirect_to_another_site() {
2338+
$filter = static function() {
2339+
return [
2340+
'response' => [
2341+
'code' => 301,
2342+
],
2343+
'headers' => [
2344+
'Location' => 'https://redirected-site.example.com/',
2345+
],
2346+
];
2347+
};
2348+
add_filter( 'pre_http_request', $filter );
2349+
$r = AMP_Validation_Manager::validate_url( home_url() );
2350+
$this->assertInstanceOf( WP_Error::class, $r );
2351+
$this->assertEquals( 'http_request_failed', $r->get_error_code() );
2352+
$this->assertStringStartsWith( 'Unable to validate a URL on another site. Attempted to validate: https://redirected-site.example.com/', $r->get_error_message() );
2353+
}
2354+
23202355
/**
23212356
* @covers AMP_Validation_Manager::serialize_validation_error_messages()
23222357
* @covers AMP_Validation_Manager::unserialize_validation_error_messages()

0 commit comments

Comments
 (0)