diff options
author | Andrew Dolgov <[email protected]> | 2023-12-29 04:38:59 +0000 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2023-12-29 04:38:59 +0000 |
commit | a882eb13f7ab36f4bab26a290a8e5ab1c6f2fb34 (patch) | |
tree | 8b5d02b95db25cd8b4487749ec27ed0602d9d7ca /classes | |
parent | 51cd02fc3e476f9e64311a87e0b84dbd16f5a44f (diff) | |
parent | 91a91dac15907bbd9bd773da9e5c6f0b7ff19f5a (diff) |
Merge branch 'feature/early-fail-disallowed-redirects' into 'master'
Perform validation of redirect URLs during the redirect process.
See merge request tt-rss/tt-rss!17
Diffstat (limited to 'classes')
-rw-r--r-- | classes/UrlHelper.php | 25 |
1 files changed, 23 insertions, 2 deletions
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 @@ <?php + +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\UriInterface; + class UrlHelper { const EXTRA_HREF_SCHEMES = [ "magnet", @@ -312,13 +317,28 @@ class UrlHelper { $req_options = [ GuzzleHttp\RequestOptions::CONNECT_TIMEOUT => $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); |