Explorar o código

Improve restriction of curl params (#8009)

Rework #7979 
Forgot to change `httpGet()`, which is used in multiple places
Inverle hai 6 meses
pai
achega
9dd30f03ec
Modificáronse 1 ficheiros con 33 adicións e 22 borrados
  1. 33 22
      lib/lib_rss.php

+ 33 - 22
lib/lib_rss.php

@@ -290,6 +290,36 @@ function sensitive_log(array|string $log): array|string {
 	return $log;
 }
 
+/**
+ * @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
@@ -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'])) {