From 9dd30f03ec8b6176de1a23ea8c3daa506103cc48 Mon Sep 17 00:00:00 2001 From: Inverle Date: Thu, 25 Sep 2025 22:50:21 +0200 Subject: Improve restriction of curl params (#8009) Rework #7979 Forgot to change `httpGet()`, which is used in multiple places --- lib/lib_rss.php | 55 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 22 deletions(-) (limited to 'lib/lib_rss.php') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 27978122a..7bcb3b58a 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -290,6 +290,36 @@ function sensitive_log(array|string $log): array|string { return $log; } +/** + * @param array $curl_params + * @return array + */ +function sanitizeCurlParams(array $curl_params): array { + $safe_params = [ + CURLOPT_COOKIE, + CURLOPT_COOKIEFILE, + CURLOPT_FOLLOWLOCATION, + CURLOPT_HTTPHEADER, + CURLOPT_MAXREDIRS, + CURLOPT_POST, + CURLOPT_POSTFIELDS, + CURLOPT_PROXY, + CURLOPT_PROXYTYPE, + CURLOPT_USERAGENT, + ]; + foreach ($curl_params as $k => $_) { + if (!in_array($k, $safe_params, true)) { + unset($curl_params[$k]); + continue; + } + // Allow only an empty value just to enable the libcurl cookie engine + if ($k === CURLOPT_COOKIEFILE) { + $curl_params[$k] = ''; + } + } + return $curl_params; +} + /** * @param array $attributes * @param array $curl_options @@ -318,28 +348,10 @@ function customSimplePie(array $attributes = [], array $curl_options = []): \Sim $curl_options[CURLOPT_SSL_CIPHER_LIST] = 'DEFAULT@SECLEVEL=1'; } } + $attributes['curl_params'] = sanitizeCurlParams(is_array($attributes['curl_params'] ?? null) ? $attributes['curl_params'] : []); if (!empty($attributes['curl_params']) && is_array($attributes['curl_params'])) { - $safe_params = [ - CURLOPT_COOKIE, - CURLOPT_COOKIEFILE, - CURLOPT_FOLLOWLOCATION, - CURLOPT_HTTPHEADER, - CURLOPT_MAXREDIRS, - CURLOPT_POST, - CURLOPT_POSTFIELDS, - CURLOPT_PROXY, - CURLOPT_PROXYTYPE, - CURLOPT_USERAGENT, - ]; foreach ($attributes['curl_params'] as $co => $v) { if (is_int($co)) { - if (!in_array($co, $safe_params, true)) { - continue; - } - if ($co === CURLOPT_COOKIEFILE) { - // Allow only an empty value just to enable the libcurl cookie engine - $v = ''; - } $curl_options[$co] = $v; } } @@ -631,7 +643,7 @@ function httpGet(string $url, string $cachePath, string $type = 'html', array $a curl_setopt_array($ch, FreshRSS_Context::systemConf()->curl_options); if (is_array($attributes['curl_params'] ?? null)) { - $options = $attributes['curl_params']; + $options = sanitizeCurlParams($attributes['curl_params']); if (is_array($options[CURLOPT_HTTPHEADER] ?? null)) { // Remove headers problematic for security $options[CURLOPT_HTTPHEADER] = array_filter($options[CURLOPT_HTTPHEADER], @@ -640,9 +652,8 @@ function httpGet(string $url, string $cachePath, string $type = 'html', array $a if (preg_grep('/^Accept\\s*:/i', $options[CURLOPT_HTTPHEADER]) === false) { $options[CURLOPT_HTTPHEADER][] = 'Accept: ' . $accept; } - $attributes['curl_params'] = $options; } - curl_setopt_array($ch, $attributes['curl_params']); + curl_setopt_array($ch, $options); } if (isset($attributes['ssl_verify'])) { -- cgit v1.2.3