From 91a91dac15907bbd9bd773da9e5c6f0b7ff19f5a Mon Sep 17 00:00:00 2001 From: wn_ Date: Fri, 29 Dec 2023 00:31:03 +0000 Subject: Perform validation of redirect URLs during the redirect process. Previously, validation was only done after all redirects and the final request had completed. This approach ensures all redirects are to URLs that pass extended validation. --- classes/UrlHelper.php | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'classes/UrlHelper.php') diff --git a/classes/UrlHelper.php b/classes/UrlHelper.php index 03202cff8..82b8bf36e 100644 --- a/classes/UrlHelper.php +++ b/classes/UrlHelper.php @@ -1,4 +1,9 @@ $timeout ?: Config::get(Config::FILE_FETCH_CONNECT_TIMEOUT), GuzzleHttp\RequestOptions::TIMEOUT => $timeout ?: Config::get(Config::FILE_FETCH_TIMEOUT), - GuzzleHttp\RequestOptions::ALLOW_REDIRECTS => $followlocation ? ['max' => 20, 'track_redirects' => true] : false, GuzzleHttp\RequestOptions::HEADERS => [ 'User-Agent' => $useragent ?: Config::get_user_agent(), ], 'curl' => [], ]; + if ($followlocation) { + $req_options[GuzzleHttp\RequestOptions::ALLOW_REDIRECTS] = [ + 'max' => 20, + 'track_redirects' => true, + 'on_redirect' => function(RequestInterface $request, ResponseInterface $response, UriInterface $uri) { + if (!self::validate($uri, true)) { + self::$fetch_effective_url = (string) $uri; + throw new GuzzleHttp\Exception\RequestException('URL received during redirection failed extended validation.', + $request, $response); + } + }, + ]; + } else { + $req_options[GuzzleHttp\RequestOptions::ALLOW_REDIRECTS] = false; + } + if ($last_modified && !$post_query) $req_options[GuzzleHttp\RequestOptions::HEADERS]['If-Modified-Since'] = $last_modified; @@ -355,7 +375,7 @@ class UrlHelper { }; # Alternative/supplement to `progress` checking - $req_options[GuzzleHttp\RequestOptions::ON_HEADERS] = function(Psr\Http\Message\ResponseInterface $response) use(&$max_size, $url) { + $req_options[GuzzleHttp\RequestOptions::ON_HEADERS] = function(ResponseInterface $response) use(&$max_size, $url) { $content_length = $response->getHeaderLine('Content-Length'); if ($content_length > $max_size) { Debug::log("[UrlHelper] fetch error: server indicated (via 'Content-Length: {$content_length}') max size of $max_size bytes " . @@ -426,6 +446,7 @@ class UrlHelper { $history_header = $response->getHeader(GuzzleHttp\RedirectMiddleware::HISTORY_HEADER); self::$fetch_effective_url = $history_header ? end($history_header) : $url; + // This shouldn't be necessary given the checks that occur during potential redirects, but we'll do it anyway. if (!self::validate(self::$fetch_effective_url, true)) { self::$fetch_last_error = "URL received after redirection failed extended validation."; $span->setAttribute('error', self::$fetch_last_error); -- cgit v1.2.3