fix(wpmc S5): wrap Redirect get_permalink + safe rest_url replacement
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -58,7 +58,7 @@ final class Redirect
|
|||||||
if (!$orig_id) {
|
if (!$orig_id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$orig_permalink = \get_permalink($orig_id);
|
$orig_permalink = Helpers::without_url_filters(static fn () => \get_permalink($orig_id));
|
||||||
if (!is_string($orig_permalink) || $orig_permalink === '') {
|
if (!is_string($orig_permalink) || $orig_permalink === '') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,13 @@ final class RestUrlFilter
|
|||||||
if ($host === '') {
|
if ($host === '') {
|
||||||
return $url;
|
return $url;
|
||||||
}
|
}
|
||||||
$replaced = preg_replace('#^https?://[^/]+#', 'https://' . $host, $url);
|
$parsed = parse_url($url);
|
||||||
return is_string($replaced) ? $replaced : $url;
|
if ($parsed === false || empty($parsed['scheme'])) {
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
$path = $parsed['path'] ?? '';
|
||||||
|
$query = isset($parsed['query']) ? '?' . $parsed['query'] : '';
|
||||||
|
$fragment = isset($parsed['fragment']) ? '#' . $parsed['fragment'] : '';
|
||||||
|
return 'https://' . $host . $path . $query . $fragment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,4 +34,16 @@ final class RestUrlFilterTest extends TestCase
|
|||||||
$url = 'https://other.example/wp-json/wp/v2/posts';
|
$url = 'https://other.example/wp-json/wp/v2/posts';
|
||||||
self::assertSame($url, RestUrlFilter::preserve_host($url));
|
self::assertSame($url, RestUrlFilter::preserve_host($url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_preserve_host_does_not_interpret_replacement_metachars_in_host(): void
|
||||||
|
{
|
||||||
|
// $_SERVER['HTTP_HOST'] is attacker-controlled (Host header).
|
||||||
|
// The replacement string must not interpret $0/\\1 as backreferences.
|
||||||
|
$_SERVER['HTTP_HOST'] = 'evil$0.com';
|
||||||
|
|
||||||
|
self::assertSame(
|
||||||
|
'https://evil$0.com/wp-json/wp/v2/posts',
|
||||||
|
RestUrlFilter::preserve_host('http://example.org/wp-json/wp/v2/posts')
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user