Skip to content

Commit 73059f9

Browse files
committed
Short-circuit validate_url() when attempting validation requests to other sites (which will always fail)
1 parent a7e7992 commit 73059f9

File tree

2 files changed

+65
-7
lines changed

2 files changed

+65
-7
lines changed

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

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,6 +1757,24 @@ public static function validate_after_plugin_activation() {
17571757
return $validation_errors;
17581758
}
17591759

1760+
/**
1761+
* Validate a URL to be validated.
1762+
*
1763+
* @param string $url URL.
1764+
* @return string|WP_Error Validated URL or else error.
1765+
*/
1766+
private static function validate_validation_url( $url ) {
1767+
$validated_url = wp_validate_redirect( $url );
1768+
if ( ! $validated_url ) {
1769+
return new WP_Error(
1770+
'http_request_failed',
1771+
/* translators: %s is the URL being redirected to. */
1772+
sprintf( __( 'Unable to validate a URL on another site. Attempted to validate: %s', 'amp' ), $url )
1773+
);
1774+
}
1775+
return $validated_url;
1776+
}
1777+
17601778
/**
17611779
* Validates a given URL.
17621780
*
@@ -1783,7 +1801,13 @@ public static function validate_url( $url ) {
17831801
self::VALIDATE_QUERY_VAR => self::get_amp_validate_nonce(),
17841802
self::CACHE_BUST_QUERY_VAR => wp_rand(),
17851803
];
1786-
$validation_url = add_query_arg( $added_query_vars, $url );
1804+
1805+
// Ensure the URL to be validated is on the site.
1806+
$validation_url = self::validate_validation_url( $url );
1807+
if ( is_wp_error( $validation_url ) ) {
1808+
return $validation_url;
1809+
}
1810+
$validation_url = add_query_arg( $added_query_vars, $validation_url );
17871811

17881812
$r = null;
17891813

@@ -1823,13 +1847,12 @@ public static function validate_url( $url ) {
18231847
$location_header = preg_replace( '#(^https?://[^/]+)/.*#', '$1', home_url( '/' ) ) . $location_header;
18241848
}
18251849

1826-
// Block redirecting to a different host.
1827-
$location_header = wp_validate_redirect( $location_header );
1828-
if ( ! $location_header ) {
1829-
break;
1850+
// Prevent following a redirect to another site, which won't work for validation anyway.
1851+
$validation_url = self::validate_validation_url( $location_header );
1852+
if ( is_wp_error( $validation_url ) ) {
1853+
return $validation_url;
18301854
}
1831-
1832-
$validation_url = add_query_arg( $added_query_vars, $location_header );
1855+
$validation_url = add_query_arg( $added_query_vars, $validation_url );
18331856
}
18341857

18351858
if ( is_wp_error( $r ) ) {

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

Lines changed: 35 additions & 0 deletions
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)