aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGravatar Inverle <inverle@proton.me> 2025-09-25 22:50:21 +0200
committerGravatar GitHub <noreply@github.com> 2025-09-25 22:50:21 +0200
commit9dd30f03ec8b6176de1a23ea8c3daa506103cc48 (patch)
tree242487dd52930a1b74d482b1e7fcea834418321d /lib
parentcec21f231f22a085cd9e8f879081fc1571848e26 (diff)
Improve restriction of curl params (#8009)
Rework #7979 Forgot to change `httpGet()`, which is used in multiple places
Diffstat (limited to 'lib')
-rw-r--r--lib/lib_rss.php55
1 files changed, 33 insertions, 22 deletions
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
@@ -291,6 +291,36 @@ function sensitive_log(array|string $log): array|string {
}
/**
+ * @param array<mixed> $curl_params
+ * @return array<mixed>
+ */
+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<string,mixed> $attributes
* @param array<int,mixed> $curl_options
* @throws FreshRSS_Context_Exception
@@ -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'])) {