From 43967a83a3b32a0881daabeb7c8c71f2aaf5df3c Mon Sep 17 00:00:00 2001 From: MDW Date: Thu, 15 Feb 2024 15:20:21 +0100 Subject: [PATCH] SEC: #28168 Correct protocol limitations (PHP7.4/Win) (#28172) # SEC: #28168 Correct protocol limitations (PHP7.4/Win) Protocol limitation was not active during test on windows platform. Moving the application of the limitation just before the curl_exec instruction made the limitation effective. Also extended the code to enable allowing ftp and ftps and extended the code for [CURLOPT_REDIR_PROTOCOLS_STR](https://www.php.net/manual/en/curl.constants.php#constant.curlopt-redir-protocols-str). --- htdocs/core/lib/geturl.lib.php | 23 +++++++++++++++++++---- test/phpunit/SecurityTest.php | 2 +- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/htdocs/core/lib/geturl.lib.php b/htdocs/core/lib/geturl.lib.php index e2bab6d4746..9d7111c44e4 100644 --- a/htdocs/core/lib/geturl.lib.php +++ b/htdocs/core/lib/geturl.lib.php @@ -1,5 +1,6 @@ + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -91,17 +92,23 @@ function getURLContent($url, $postorget = 'GET', $param = '', $followlocation = // Restrict use to some protocols only $protocols = 0; + $redir_list = array(); if (is_array($allowedschemes)) { foreach ($allowedschemes as $allowedscheme) { if ($allowedscheme == 'http') { $protocols |= CURLPROTO_HTTP; - } - if ($allowedscheme == 'https') { + $redir_list["HTTP"] = 1; + } elseif ($allowedscheme == 'https') { $protocols |= CURLPROTO_HTTPS; + $redir_list["HTTPS"] = 1; + } elseif ($allowedscheme == 'ftp') { + $protocols |= CURLPROTO_FTP; + $redir_list["FTP"] = 1; + } elseif ($allowedscheme == 'ftps') { + $protocols |= CURLPROTO_FTPS; + $redir_list["FTPS"] = 1; } } - curl_setopt($ch, CURLOPT_PROTOCOLS, $protocols); - curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS, $protocols); } curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, !getDolGlobalString('MAIN_USE_CONNECT_TIMEOUT') ? 5 : $conf->global->MAIN_USE_CONNECT_TIMEOUT); @@ -219,6 +226,14 @@ function getURLContent($url, $postorget = 'GET', $param = '', $followlocation = } } + // Moving these just before the curl_exec option really limits + // on windows PHP 7.4. + curl_setopt($ch, CURLOPT_PROTOCOLS, $protocols); + curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS, $protocols); + if (version_compare(PHP_VERSION, '8.3.0', '>=') && version_compare(curl_version()['version'], '7.85.0', '>=')) { + curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS_STR, implode(",", array_keys($redir_list))); + } + // Getting response from server $response = curl_exec($ch); diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 72a7375ec0b..0e800a65c6f 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -918,7 +918,7 @@ class SecurityTest extends PHPUnit\Framework\TestCase $url = 'ftp://mydomain.com'; $tmp = getURLContent($url); print __METHOD__." url=".$url."\n"; - $this->assertGreaterThan(0, strpos($tmp['curl_error_msg'], 'not supported')); // Test error if return does not contains 'not supported' + $this->assertRegExp("/not supported/", $tmp['curl_error_msg'], "Should disable ftp connection"); // Test error if return does not contains 'not supported' $url = 'https://www.dolibarr.fr'; // This is a redirect 301 page $tmp = getURLContent($url, 'GET', '', 0); // We do NOT follow