summaryrefslogtreecommitdiff
path: root/classes
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2023-12-29 04:38:59 +0000
committerAndrew Dolgov <[email protected]>2023-12-29 04:38:59 +0000
commita882eb13f7ab36f4bab26a290a8e5ab1c6f2fb34 (patch)
tree8b5d02b95db25cd8b4487749ec27ed0602d9d7ca /classes
parent51cd02fc3e476f9e64311a87e0b84dbd16f5a44f (diff)
parent91a91dac15907bbd9bd773da9e5c6f0b7ff19f5a (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.php25
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);